如何将一对多关系数据集作为一列减少/合并到另一个数据集中

时间:2018-01-30 04:31:15

标签: apache-spark spark-dataframe

我是Spark和Stackoverflow的新手,并试图找出这个问题,不确定我的主题是否可描述。任何帮助/建议将不胜感激。

我有两个数据集,一个只有ID,如下所示:

ID
111
222

另一个包含ID,parent_ID和Role,其中parent_ID链接到上一个表中的ID,

ID      Parent_ID      Role
444      111           Editor
555      111           Manager
666      222           Editor

我想要制作的是这样的数据集:

ID   isEditor   isManager
111   True       True
222   True       False

我最初的想法是通过id / parent-id连接两个表,然后将多行缩减/合并为一个,但是在缩减/合并部分时遇到问题。

非常感谢任何帮助/建议。

1 个答案:

答案 0 :(得分:2)

这可以通过仅使用第二个数据帧来解决,第一个数据帧不是必需的。使用与问题中相同的数据:

val df = Seq((444, 111, "Editor"), (555, 111, "Manager"), (666, 222, "Editor")).toDF("ID", "Parent_ID", "Role") 

val df2 = df.groupBy("Parent_ID").agg(collect_list($"Role").as("Roles"))
  .withColumn("isEditor", when(array_contains($"Roles", "Editor"), "True").otherwise("False"))
  .withColumn("isManager", when(array_contains($"Roles", "Manager"), "True").otherwise("False"))
  .drop("Roles")

这将产生预期的结果:

+---------+--------+---------+
|Parent_ID|isEditor|isManager|
+---------+--------+---------+
|      222|    True|    False|
|      111|    True|     True|
+---------+--------+---------+

解决方案首先聚合包含所有可能角色的每个Parent_ID的列表。然后,isEditorisManager列设置为true或false,具体取决于角色是否在列表中,或者使用内置的array_contains方法。最后,删除包含角色列表的临时Roles列。