如何使用Spark Scala中的Graph.fromEdgeTuples从CSV文件创建图表

4
我是Spark和Scala的新手,正在尝试从文本文件中创建一个图形来执行简单的任务。
从文档中可以看到:

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

我可以看到我可以从“顶点元组”创建一个图表。
我的简单文本文件看起来像这样,其中每个数字都是一个顶点:
v1 v3
v2 v1
v3 v4
v4
v5 v3

当我从文件中读取数据时,

val myVertices = myData.map(line=>line.split(" ")) I get an RDD[Array[String]].

我的问题是:
  1. 如果这是解决问题的正确方法,如何将 RDD[Array[String]] 转换为正确的格式,根据文档,正确的格式应该是 RDD[(VertexId, VertexId)](还要求 VertexID 的类型为 long,而我正在使用字符串)。

  2. 是否有另一种更简单的方法,可以从类似 csv 文件的结构构建图形?

欢迎任何建议。谢谢!
4个回答

5

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

这段代码使用 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 用于将字符串形式的顶点哈希编码。如果顶点是数值类型,则不需要使用该方法。


非常感谢,这段代码:val edgesRDD: RDD[(VertexId, VertexId)] = file.map(line => line.split(" ")) .map(line => (MurmurHash.stringHash(line(0).toString), MurmurHash.stringHash(line(1).toString))) 恰好是我正在寻找的。 - Adelina Balasa

0

你可以使用一个好的哈希函数将字符串值转换为长整型。


0
首先,您应该阅读并理解Spark编程指南:https://spark.apache.org/docs/1.1.0/graphx-programming-guide.html 接下来,您需要确定在图形中表示什么类型的边缘和顶点。鉴于您似乎没有任何东西可以附加到您的顶点和边缘上,因此您需要类似以下内容的东西:
type MyVertex = (Long,Unit)

如果你发现你有一些要附加到每个顶点的东西,比如一个字符串,那么将 Unit 替换为 String,并在下面将 null 替换为适当的字符串。

现在你需要一个顶点数组(或其他 Seq),然后将其转换为 RDD——类似于这样:

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)

我在自己的应用程序中有类似的代码,我已经尝试将其调整为您所需的内容,但我不能保证这会完美无缺。但它应该能让您开始。


-1

如果你的文件是以边列表格式,例如

v1 v3
v2 v1
v3 v4
v5 v3

然后您可以简单地使用以下内容,它将从边的端点计算出顶点:

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

然而,按照当前状态,“v4”本身意味着edgeListFile会抛出异常。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接