如何将一个数据集的列(也包括多列)中的值映射到另一数据集

时间:2019-03-25 09:59:16

标签: scala apache-spark dataframe dataset graphframes

我正在图框部分工作,我需要在d3.js中具有边/链接以将Vertex /节点的索引值作为源和目标。

现在我有VertexDF作为

+--------------------+-----------+
|                  id|      rowID|
+--------------------+-----------+
|      Raashul Tandon|          3|
|         Helen Jones|          5|
----------------------------------

EdgesDF

+-------------------+--------------------+
|                src|                 dst|
+-------------------+--------------------+
|     Raashul Tandon|    Helen Jones     |
------------------------------------------

现在我需要按如下方式转换此EdgesDF

+-------------------+--------------------+
|                src|                 dst|
+-------------------+--------------------+
|     3             |            5       |
------------------------------------------

所有列值都应具有从VertexDF提取的名称的索引。我期望在Higher-order functions中使用。 我的方法是将VertexDF转换为映射,然后迭代EdgesDF并替换所有出现的事件。

我尝试过的事情

将姓名映射到ID

val Actmap = VertxDF.collect().map(f =>{
  val name = f.getString(0)
  val id = f.getLong(1)
  (name,id)
})
.toMap

将该地图用于EdgesDF

EdgesDF.collect().map(f => {
  val src = f.getString(0)
  val dst = f.getString(0)

  val src_id = Actmap.get(src)
  val dst_id = Actmap.get(dst)
  (src_id,dst_id)
})

1 个答案:

答案 0 :(得分:0)

您使用collect处理顶点和边缘数据帧的方法只有在它们很小的情况下才有效。我建议left-加入边缘和顶点数据框以获得所需的内容:

import org.apache.spark.sql.functions._
import spark.implicits._

val VertxDF = Seq(
  ("Raashul Tandon", 3),
  ("Helen Jones", 5),
  ("John Doe", 6),
  ("Rachel Smith", 7)
).toDF("id", "rowID")

val EdgesDF = Seq(
  ("Raashul Tandon", "Helen Jones"),
  ("Helen Jones", "John Doe"),
  ("Unknown", "Raashul Tandon"),
  ("John Doe", "Rachel Smith")
).toDF("src", "dst")

EdgesDF.as("e").
  join(VertxDF.as("v1"), $"e.src" === $"v1.id", "left_outer").
  join(VertxDF.as("v2"), $"e.dst" === $"v2.id", "left_outer").
  select($"v1.rowID".as("src"), $"v2.rowID".as("dst")).
  show
// +----+---+
// | src|dst|
// +----+---+
// |   3|  5|
// |   5|  6|
// |null|  3|
// |   6|  7|
// +----+---+