2015-09-04 254 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

您可以使用一個很好的散列函數將字符串值轉換爲長整型。

相關問題