2015-09-04 52 views
3

我是SparkScala的新手,我试图执行从文本文件中的数据创建图形的简单任务。如何使用Spark Scala中的Graph.fromEdgeTuples从CSV文件创建图形

从文档

https://spark.apache.org/docs/0.9.0/api/graphx/index.html#org.apache.spark.graphx.Graph $ @ fromEdges [VD,ED]%28RDD [边缘[ED],VD%29%28ClassTag [VD],ClassTag [ED]%29:图[VD,ED]

我可以看到我可以从tuples of vertices创建一个图表。

我简单的文本文件看起来像这样,每个数字是一个顶点:

v1 v3 
v2 v1 
v3 v4 
v4 
v5 v3 

当我从文件中读取

VAL myVertices = myData.map数据(线=> line.split(“”)) 我得到一个RDD [数组[String]]。

我的问题是:

  1. 如果这是解决这个问题的正确方法,我怎么转RDD[Array[String]]成正确的格式,其中根据文档RDD[(VertexId, VertexId)](也VertexID必须是long类型的,而且我正在使用字符串)

  2. 是否有其他替代方法,我可以通过类似于csv文件的结构构建图表?

任何建议将是非常受欢迎的。谢谢!

回答

0

首先,你应该阅读并理解星火编程指南:https://spark.apache.org/docs/1.1.0/graphx-programming-guide.html

接下来,你需要确定你会在你的图代表什么样的边缘和顶点的。既然你似乎有什么附加到您的顶点和边,它看起来像你需要的东西,如:

type MyVertex = (Long,Unit) 

如果你发现你确实有一些东西,像一个字符串,附加到每一个顶点,然后更换以字符串为单位,并在下面用适当的String替换null。

现在,您需要的顶点,你再转换为RDD数组(或其他SEQ) - 是这样的:

val vertices: Seq[MyVertex] = Array(new MyVertex(1L,null),new MyVertex(2L,null),new MyVertex(3L,null)) 
val rddVertices: RDD[(VertexId, Unit)] = sc.parallelize(vertices) 

其中SC是你SparkContext的实例。并且您的顶点和边缘从您的CSV文件中读取并适当地转换为长整型。我不会详细说明该代码,但它很简单,特别是如果您更改CSV文件的格式以从每个顶点ID中删除“v”前缀。

同样,你必须创建一个你想要的边缘:

type MyEdge = Edge[Unit] 
val edge1 = new MyEdge(1L,2L) 
val edge2 = new MyEdge(2L,3L) 
val edges = Array(edge1,edge2) 
val rdd = sc.parallelize(edges) 

最后,创建您的图表:

val graph = Graph(rddVertices,rddEdges) 

我有我自己的应用程序类似的代码,我曾尝试按摩到你需要的东西,但我不能保证这将是完美的。但它应该让你开始。

3

有许多方法可以从文本文件创建图形。

此代码创建从Graph.fromEdgeTuples方法的曲线图

import org.apache.spark.SparkConf 
import org.apache.spark.SparkContext 
import org.apache.spark.graphx.GraphLoader 
import scala.util.MurmurHash 
import org.apache.spark.graphx.Graph 
import org.apache.spark.rdd.RDD 
import org.apache.spark.graphx.VertexId 

object GraphFromFile { 
    def main(args: Array[String]) { 

    //create SparkContext 
    val sparkConf = new SparkConf().setAppName("GraphFromFile").setMaster("local[*]") 
    val sc = new SparkContext(sparkConf) 

    // read your file 
    /*suppose your data is like 
    v1 v3 
    v2 v1 
    v3 v4 
    v4 v2 
    v5 v3 
    */ 
    val file = sc.textFile("src/main/resources/textFile1.csv"); 

    // create edge RDD of type RDD[(VertexId, VertexId)] 
    val edgesRDD: RDD[(VertexId, VertexId)] = file.map(line => line.split(" ")) 
     .map(line => 
     (MurmurHash.stringHash(line(0).toString), MurmurHash.stringHash(line(1).toString))) 

    // create a graph 
    val graph = Graph.fromEdgeTuples(edgesRDD, 1) 

    // you can see your graph 
    graph.triplets.collect.foreach(println) 

    } 
} 

MurmurHash.stringHash被使用,因为文件包含字符串的形式顶点。如果它的数字类型,那么它不会被要求。

+0

非常感谢,这位:val edgesRDD:RDD [(VertexId,VertexId)] = file.map(line => line.split(“”)) .map(line => (MurmurHash.stringHash (line(0).toString),MurmurHash.stringHash(line(1).toString)))正是我正在寻找 –

0

如果您的文件处于边缘列表格式,例如

v1 v3 
v2 v1 
v3 v4 
v5 v3 

,那么你可以简单地使用下面将制定出什么样的顶点是从边缘的端点:

import org.apache.spark.graphx._ 
val graph = GraphLoader.edgeListFile(sc, "so_test.txt") 

然而,因为它代表它自己的手段是“V4”那edgeListFile抛出异常

0

您可以使用一个很好的散列函数将字符串值转换为长整型。

相关问题