如何获取转换DataFrame到特定的RDD?

时间:2018-01-03 14:40:33

标签: scala apache-spark

我在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吗?

1 个答案:

答案 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属性。