我是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:图形[VD,ED]
我可以看到我可以从tuples of vertices
创建图表。
我的简单文本文件如下所示,其中每个数字都是一个顶点:
v1 v3
v2 v1
v3 v4
v4
v5 v3
当我从文件中读取数据时
val myVertices = myData.map(line => line.split("")) 我得到一个RDD [Array [String]]。
我的问题是:
如果这是解决问题的正确方法,请如何将RDD[Array[String]]
转换为正确的格式,根据文档RDD[(VertexId, VertexId)]
(VertexID
必须是类型长,我正在使用字符串)
我是否有另一种更简单的方法可以从类似的csv文件结构构建图形?
任何建议都会非常受欢迎。谢谢!
答案 0 :(得分: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 ,因为文件包含String形式的顶点。如果它是Numeric类型,则不需要它。
答案 1 :(得分:0)
首先,您应该阅读并理解Spark编程指南:https://spark.apache.org/docs/1.1.0/graphx-programming-guide.html
接下来,您需要确定要在图表中表示的边缘和顶点类型。鉴于您似乎没有任何东西可以附加到您的顶点和边缘,看起来您需要类似的东西:
type MyVertex = (Long,Unit)
如果你发现你确实有一些东西,比如String,要附加到每个顶点,然后用字符串替换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文件中读取并适当地转换为long。我不会详细说明该代码,但它很简单,特别是如果您更改CSV文件的格式以删除" v"来自每个顶点id的前缀。
同样,您必须创建所需的边缘:
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)
我在自己的应用程序中有类似的代码,我试图按摩你需要的东西,但我无法保证这将是完美的。但它应该让你开始。
答案 2 :(得分:0)
如果您的文件是边缘列表格式,例如
---
- hosts: localhost
connection: local
gather_facts: false
tasks:
- name: 'Calling Python Code to reserve instance'
raw: python reserve-ec2-instance.py args
然后您可以简单地使用以下内容来计算顶点来自边缘端点的内容:
v1 v3
v2 v1
v3 v4
v5 v3
然而,因为它代表了' v4'它自己的意思是edgeListFile抛出异常
答案 3 :(得分:0)
你可以使用一个好的哈希函数将字符串值转换为long。