【问题标题】:How to reduce/merge one-to-many relationship dataset into another dataset as one column如何将一对多关系数据集作为一列减少/合并到另一个数据集中
【发布时间】:2018-01-30 14:33:58
【问题描述】:

我对 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连接两个表,然后将多行reduce/merge为一个,但是reduce/merge部分有问题。

任何帮助/建议将不胜感激。

【问题讨论】:

  • 为什么需要第一个表?你不能在 parent_id 上分组并从那里开始吗?
  • 前两个表是我从 csv 文件中获得的数据集。它包含其他一些列,但与我的问题无关,所以我没有提到它们
  • 所以,对于这个问题,您实际上并不需要第一个数据集。对吗?
  • 我需要它,要生成的数据集需要包含我没有提到的所有其他列。换一种说法,我需要在我的第一个数据集中再添加两列:“isEdittor”和“isManager”,列的值(真或假)基于第二个数据集中的数据。跨度>
  • 是的,当然。但是对于这个问题,似乎重点是如何添加这两列。连接本身并没有那么有趣,对吗?否则需要更多信息,即当 id 存在于第一个数据帧中但不存在第二个数据帧时会发生什么,反之亦然。正如问题目前看起来的那样,它可以只使用第二个数据集的 parent_id 和 role 列来解决,这使得第一个数据集变得不必要(因此我问你为什么需要加入)。

标签: apache-spark spark-dataframe


【解决方案1】:

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

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 聚合一个列表,其中包含所有可能的角色。然后使用内置的array_contains 方法将isEditorisManager 列设置为true 或false,具体取决于角色是否在列表中。最后,包含角色列表的临时 Roles 列被删除。

【讨论】:

  • 工作顺利!谢谢!!
猜你喜欢
  • 2011-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-09
  • 1970-01-01
  • 2015-09-14
  • 1970-01-01
  • 2021-12-27
相关资源
最近更新 更多