4

我是 and 的新手SparkScala我正在尝试执行一项简单的任务,即从文本文件中的数据创建图形。

从文档

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]

我可以看到我可以从tuples of vertices.

我的简单文本文件如下所示,其中每个数字都是一个顶点:

v1 v3
v2 v1
v3 v4
v4
v5 v3

当我从文件中读取数据时

val myVertices = myData.map(line=>line.split(" ")) 我得到一个 RDD[Array[String]]。

我的问题是:

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

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

任何建议都会非常受欢迎。谢谢!

4

4 回答 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是因为文件包含 String 形式的顶点。如果它是数字类型,则不需要。

于 2015-09-06T06:03:31.307 回答
0

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

接下来,您需要确定将在图表中表示的边和顶点的类型。鉴于您似乎没有任何东西可以附加到您的顶点和边缘,看起来您需要类似的东西:

type MyVertex = (Long,Unit)

如果你发现你确实有一些东西,比如字符串,要附加到每个顶点,然后用字符串替换 Unit,然后在下面用适当的字符串替换 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)

我在自己的应用程序中有类似的代码,我试图将其调整为您需要的内容,但我不能保证这将是完美的。但它应该让你开始。

于 2015-09-04T13:45:28.397 回答
0

您可以使用良好的哈希函数将字符串值转换为长整数。

于 2018-01-16T07:34:19.927 回答
-1

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

v1 v3
v2 v1
v3 v4
v5 v3

那么您可以简单地使用以下内容来计算顶点来自边的端点:

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

然而,就其本身而言,'v4' 意味着 edgeListFile 抛出异常

于 2015-09-09T10:28:52.957 回答