Scala 公共元素的火花合并集
我有一个如下所示的数据帧:Scala 公共元素的火花合并集,scala,apache-spark,Scala,Apache Spark,我有一个如下所示的数据帧: +-----------+-----------+ | Package | Addresses | +-----------+-----------+ | Package 1 | address1 | | Package 1 | address2 | | Package 1 | address3 | | Package 2 | address3 | | Package 2 | address4 | | Package 2 | address5 | |
+-----------+-----------+
| Package | Addresses |
+-----------+-----------+
| Package 1 | address1 |
| Package 1 | address2 |
| Package 1 | address3 |
| Package 2 | address3 |
| Package 2 | address4 |
| Package 2 | address5 |
| Package 2 | address6 |
| Package 3 | address7 |
| Package 3 | address8 |
| Package 4 | address9 |
| Package 5 | address9 |
| Package 5 | address1 |
| Package 6 | address10 |
| Package 7 | address8 |
+-----------+-----------+
我需要找到在不同包中看到的所有地址。示例输出:
+----+------------------------------------------------------------------------+
| Id | Addresses |
+----+------------------------------------------------------------------------+
| 1 | [address1, address2, address3, address4, address5, address6, address9] |
| 2 | [address7, address8] |
| 3 | [address10] |
+----+------------------------------------------------------------------------+
所以,我有数据帧。我通过包对其进行分组(而不是分组):
然后,我合并具有公共地址的行:
val result = rdd.treeAggregate(
Set.empty[Set[String]]
)(
(map: Set[Set[String]], row) => {
val vals = row._2
val sets = map + vals
// copy-paste from here https://stackoverflow.com/a/25623014/772249
sets.foldLeft(Set.empty[Set[String]])((cum, cur) => {
val (hasCommon, rest) = cum.partition(_ & cur nonEmpty)
rest + (cur ++ hasCommon.flatten)
})
},
(map1, map2) => {
val sets = map1 ++ map2
// copy-paste from here https://stackoverflow.com/a/25623014/772249
sets.foldLeft(Set.empty[Set[String]])((cum, cur) => {
val (hasCommon, rest) = cum.partition(_ & cur nonEmpty)
rest + (cur ++ hasCommon.flatten)
})
},
10
)
但是,无论我做什么,treeaggreegate
都要花很长时间,而且我无法完成一项任务。原始数据大小约为250gb。我尝试了不同的集群,但是treeaggreegate
花费的时间太长
TreeAgGragate
之前的一切都很好,但之后的一切都很糟糕
我尝试了不同的spark.sql.shuffle.partitions
(默认值为2000、10000),但这似乎并不重要
我尝试了不同的深度
用于treeaggreegate
,但没有注意到差异
相关问题:
看看你的数据,就好像它是一个图,其中地址是顶点,如果它们都有一个包,它们就有一个连接。然后,您的问题的解决方案将是图形 Sparks gpraphX库具有优化的查找函数。它将返回不同连接组件中的顶点,将它们视为每个连接组件的ID 然后,如果需要,您可以收集连接到它的所有其他地址
看看他们是如何使用图形来实现与您相同的分组的。看看您的数据,就好像它是一个以地址为顶点的图形,如果它们都有包,它们就有一个连接。然后,您的问题的解决方案将是图形 Sparks gpraphX库具有优化的查找函数。它将返回不同连接组件中的顶点,将它们视为每个连接组件的ID 然后,如果需要,您可以收集连接到它的所有其他地址
看看他们是如何使用图形实现与您相同的分组的。我不确定我是否理解您的意图。为什么不这样做:packages.groupBy(“packages”).agg(collect_set(“address”)?@AssafMendelson,因为它将给出与我需要的完全不同的结果。请仔细查看预期结果。如果我分组,我会得到7个不同的结果,但我预期只有三个。@AssafMendelson示例:address4和address1属于一起,即使它们属于不同的包,因为address3已经出现在package1和package2中。因此,package1和package2中的所有地址都属于同一个地址,依此类推。我不确定我是否理解您的意图。为什么不这样做:packages.groupBy(“packages”).agg(collect_set(“address”)?@AssafMendelson,因为它将给出与我需要的完全不同的结果。请仔细查看预期结果。如果我分组,我会得到7个不同的结果,但我预期只有三个。@AssafMendelson示例:address4和address1属于一起,即使它们属于不同的包,因为address3已经出现在package1和package2中。因此,package1和package2中的所有地址都属于同一个地址,依此类推。
val result = rdd.treeAggregate(
Set.empty[Set[String]]
)(
(map: Set[Set[String]], row) => {
val vals = row._2
val sets = map + vals
// copy-paste from here https://stackoverflow.com/a/25623014/772249
sets.foldLeft(Set.empty[Set[String]])((cum, cur) => {
val (hasCommon, rest) = cum.partition(_ & cur nonEmpty)
rest + (cur ++ hasCommon.flatten)
})
},
(map1, map2) => {
val sets = map1 ++ map2
// copy-paste from here https://stackoverflow.com/a/25623014/772249
sets.foldLeft(Set.empty[Set[String]])((cum, cur) => {
val (hasCommon, rest) = cum.partition(_ & cur nonEmpty)
rest + (cur ++ hasCommon.flatten)
})
},
10
)