我在Spark 2.2中有以下DataFrame:
df =
v_in v_out
123 456
123 789
456 789
此df
定义图表的边缘。每行是一对顶点。我想提取边缘数组,以便创建RDD
边,如下所示:
val edgeArray = Array(
Edge(2L, 1L, 0.0),
Edge(2L, 4L, 0.2),
Edge(3L, 2L, 0.9),
Edge(3L, 6L, 0.1),
Edge(4L, 1L, 0.0),
Edge(5L, 2L, 0.8),
Edge(5L, 3L, 0.7),
Edge(5L, 6L, 0.5)
)
val spark = SparkSession.builder()
.appName("ES")
.master("local[*]")
.getOrCreate()
implicit val sparkContext = spark.sparkContext
val edgeRDD: RDD[Edge[Double]] = sparkContext.parallelize(edgeArray)
如何使用edgeArray
获取相同结构的df
?在每个Edge中,第三个值可以是0到1之间的任意随机Double值。
更新:
我是这样做的,但不确定这是否是最佳解决方案:
val edgeArray = df.rdd.collect().map(row => Edge(row.get(0).toString.toLong, row.get(1).toString.toLong, 0.0))
val edgeRDD: RDD[Edge[Double]] = sparkContext.parallelize(edgeArray)
我不喜欢使用Array
,因为我可能有数百万个边缘。我可以更直接地将DataFrame传递给RDD吗?
答案 0 :(得分:3)
鉴于
val df = Seq((123, 456), (123, 789), (456, 789)).toDF("v_in", "v_out")
导入
import org.apache.spark.sql.functions.rand
import org.apache.spark.graphx.Edge
并转换:
val edgeRDD = df.toDF("srcId", "dstId")
.withColumn("attr", rand)
.as[Edge[Double]].rdd
使用graphframes
:
spark.jars.packages graphframes:graphframes:X.X.X-sparkY.Y-s_Z.ZZ
其中X.X.X
是包版本,Y.Y
是Spark版本而Z.ZZ
是Scala版本,您可以像这样创建Graph
:
GraphFrame.fromEdges(df.toDF("src", "dst")).toGraphX
但它会使用Row
属性。