如何从文件中读取数据(GraphX)?

问题描述 投票:0回答:1

我是Scala的新手,我正试图从文本文件中将无向图读作图形(GraphX)。文本文件的格式为:

1,8,9,10
2,5,6,7,3,1

表示节点1连接到节点8,9和10(邻接列表),节点2连接到节点5,6,7,3,1。

我试图将其读作图形(GraphX)

我正在尝试使用fromEdge [VD,ED]方法(GraphX)完成此操作,我必须传递成对的边。

 val graph = sc.textFile("Path to file").map(line=>line.split(",").map(line=>line.toLong)).map{case Array(a,z @ _*)=>(z.map(m=>(a,m) ))}

这给了我,

Vector((1,8), (1,9), (1,10))
Vector((2,5), (2,6), (2,7), (2,3), (2,1))

由于图形是Unit类型,因此不能与fromEdge方法(GraphX)一起使用。

我无法找到一种方法来制作这些边缘。有一个更好的方法吗?

任何人都可以帮助我,或者为我提供一些可能对我有帮助的资源吗?

scala apache-spark spark-graphx
1个回答
0
投票

我想有很多版本的解决方案可以用Spark / Scala编写,从你指定的文件格式加载图形。

以下是使用RDD的动态解决方案示例:

// Loading sample data
scala> val graphData = sc.parallelize(Seq("1, 8, 9, 10", "2,5,6,7,3,1"))
graphData: org.apache.spark.rdd.RDD[String] = ParallelCollectionRDD[5]

// Trim whitespaces and map the String into an Array[Long]
scala> val graphList = graphData.map( x => {
     |    x.replace(" ", "").split(",").map(_.toLong)
     | })
graphList: org.apache.spark.rdd.RDD[Array[Long]] = MapPartitionsRDD[6]

// Here is how graphList looks like now
scala> graphList.collect
res11: Array[Array[Long]] = Array(Array(1, 8, 9, 10), Array(2, 5, 6, 7, 3, 1))

// Generating edges by crossProduct element(0) with the rest of Array elements
scala> val edges = graphList.flatMap(x => x.drop(1).map(y => (x(0), y) )).map(x => Edge(x._1, x._2, "attr"))
edges: Array[org.apache.spark.graphx.Edge[String]] = Array(Edge(1,8,attr), Edge(1,9,attr), Edge(1,10,attr), Edge(2,5,attr), Edge(2,6,attr), Edge(2,7,attr), Edge(2,3,attr), Edge(2,1,attr))

// Generating vertices, and adding name/attr for each vertex
scala> val vertices = graphList.flatMap(x => x).map(x => (x, ("name", "attr"))).distinct.sortBy(x => x)
vertices: org.apache.spark.rdd.RDD[(Long, (String, String))] = MapPartitionsRDD

//A default value is defined in case a connection or vertex is missing; the graph is then constructed from the RDD-based structures vertices and edges and the default record:
val default = ("Unknown", "Missing")

// Finally, declare your Graph
scala> val graph = Graph(vertices, edgesRDD, default)
graph: org.apache.spark.graphx.Graph[(String, String),String] = org.apache.spark.graphx.impl.GraphImpl@8097e8f

// Checking how vertices look like
scala> graph.vertices.collect
res26: Array[(org.apache.spark.graphx.VertexId, (String, String))] = Array((8,(name,attr)), (1,(name,attr)), (9,(name,attr)), (10,(name,attr)), (2,(name,attr)), (3,(name,attr)), (5,(name,attr)), (6,(name,attr)), (7,(name,attr)))

请注意,您还应该考虑分区(并行)和缓存(顶点,边缘)以进一步优化您的工作。

构造图的更好方法

GraphFrames现在是GraphX的更好替代品,它受益于DataFrames的可扩展性和高性能。

我鼓励您阅读并尽可能地开始使用它。

一种更原生的格式,用于表示GraphX或GraphFrames的图形

例如,这里的顶点文件只包含六行。每个顶点代表一个人,并具有顶点ID号,名称和属性,在本例中为年龄值:

1,Mike,48
2,Sarah,45
3,John,25
4,Jim,53
5,Kate,22
6,Flo,52

另一个边文件包含源顶点ID,目标顶点ID和关系形式的一组有向边值。因此,记录1形成Flo和Mike之间的姐妹关系:

6,1,Sister
1,2,Husband
2,1,Wife
5,1,Daughter
5,2,Daughter
3,1,Son
3,2,Son
4,1,Friend
1,5,Father
1,3,Father
2,5,Mother
2,3,Mother

现在您的代码将变得如此简单:

val vertex = spark.read.option("header","true").load("csvgraph1_vertex.csv")
val edges = spark.read.option("header","true").load("csvgraph1_edges.csv")
val graph = GraphFrame(vertex, edges)

更新

GraphFrames与GraphX集成

GraphFrames通过两种表示之间的转换与GraphX完全集成,没有任何数据丢失。我们可以将图形转换为GraphX图形并返回GraphFrame。

val gx: Graph[Row, Row] = g.toGraphX()
val g2: GraphFrame = GraphFrame.fromGraphX(gx)
© www.soinside.com 2019 - 2024. All rights reserved.