【问题标题】:How to find all two pairs of sets and elements in a collection using MapReduce in Spark?如何在 Spark 中使用 MapReduce 查找集合中的所有两对集合和元素?
【发布时间】:2018-06-30 20:22:53
【问题描述】:

我有一组集合,每个集合包含许多项目。我想使用 Spark 检索所有成对的集合和元素,其中减少处理后的每一对将包含两个项目和两个集合 例如:

如果我有这个集合列表

Set A={1,2,3,4 }
Set B={1,2,4,5}
Set C= {2,3,5,6}

映射过程将是:

(A,1)
(A,2)
(A,3)
(B,1)
(B,2)
(B,4)
(B,5)
(C,2)
(C,3)
(C,5)
(C,6)

reduce后的目标结果是:

(A B, 1 2) // since 1 2 exist in both A and B
(A B, 1 4)
(A B, 2 4)
(A C,2 3)
(B C,2 5) 
here (A B,1 3) not in the result because 1 3 not exists in B

您能帮我用任何语言(Python、Scala 或 Java)在一个 map 和一个 reduce 函数中解决 Spark 中的这个问题吗?

【问题讨论】:

  • 这可能是一个很好的代码高尔夫问题codegolf.stackexchange.com
  • 你能分享代码来创建你的rdd而不是python对象吗?
  • 实际上,我是新来的火花。我正在寻找任何可以帮助我解决这个问题的算法。感谢您的帮助

标签: apache-spark collections mapreduce set reduce


【解决方案1】:

让我们把这个问题分解成多个部分,我认为从输入列表到映射输出的转换是微不足道的。所以让我们从那里开始,

你有一个看起来像 (String, int) 的列表

("A", 1)
("A", 2)
....

让我们先忘记结果集中需要 2 个整数元素,然后让我们解决从映射输出中获取任意 2 个键之间的交集的问题。

您输入的结果如下所示

(AB, Set(1,2,4))
(BC, Set(2,5))
(AC, Set(2,3))

为此,首先,从映射输出 (mappedOutput) 中提取所有键,它是 (String, Int) 的 RDD,转换为 set,并获取 2 个元素的所有组合(我在这里使用了一种愚蠢的方法,做到这一点的一个好方法是使用组合生成器)

val combinations = mappedOutput.map(x => x._1).collect.toSet
.subsets.filter(x => x.size == 2).toList
.map(x => x.mkString(""))

输出将是 List(ab,ac,bc),这些组合代码将用作要连接的键。

将映射输出转换为集合键列表 (a,b,c) => 元素集

val step1 = mappedOutput.groupByKey().map(x => (x._1, x._2.toSet)) 

将组合代码作为键附加到步骤1

val step2 = step1.map(x => combinations.filter(y => y.contains(x._1)).map(y => (y, x))).flatMap(x => x)

输出将是 (ab, (a, a) 中的一组元素), (ac, (a, a) 中的一组元素) 等。由于过滤器的原因,我们不会附加组合代码 bc 来设置 a .

现在使用 reduce 获得我想要的结果

val result = step2.reduceByKey((a, b) => ("", a.intersect(b))).map(x => (x._1, x._2._2))

所以我们现在有了我提到的我们想要的输出。剩下的就是把这个结果转换成你需要的,这很简单。

val transformed = result.map(x => x._2.subsets.filter(x => x.size == 2).map(y => (x._1, y.mkString(" ")))).flatMap(x => x)

结束:)

【讨论】:

  • 谢谢郝远。你的解决方案非常好。我希望我能把它点在一张地图和一个reduce函数中
  • @AbdulrahmanMohammed 恐怕只用一个 map 和一个 reduce 函数来做到这一点,你需要对输入做一些假设。您需要假设您事先已经知道组合(设置 ID),并且您需要假设传递给您的输入已经采用 step1 的格式。
猜你喜欢
  • 2012-10-31
  • 1970-01-01
  • 1970-01-01
  • 2023-04-02
  • 1970-01-01
  • 2014-04-29
  • 1970-01-01
  • 2021-10-22
  • 2021-10-26
相关资源
最近更新 更多