Apache Spark - 多个RDD的交集

时间:2016-10-27 15:14:10

标签: scala apache-spark

在apache spark中,可以使用sparkContext.union()方法有效地联合多个RDD。如果有人想要交叉多个RDD,是否有类似的东西?我在sparkContext方法中搜索过,找不到任何东西或其他任何东西。一种解决方案可能是联合rdds然后检索重复项,但我认为它不会那么高效。假设我有以下关键/值对集合的示例:

val rdd1 = sc.parallelize(Seq((1,1.0),(2,1.0)))
val rdd2 = sc.parallelize(Seq((1,2.0),(3,4.0),(3,1.0)))

我想要检索一个包含以下元素的新集合:

(1,2.0) (1,1.0)

但当然对于多个rdds而不仅仅是两个。

2 个答案:

答案 0 :(得分:2)

尝试:

val rdds = Seq(
  sc.parallelize(Seq(1, 3, 5)),
  sc.parallelize(Seq(3, 5)),
  sc.parallelize(Seq(1, 3))
)
rdds.map(rdd => rdd.map(x => (x, None))).reduce((x, y) => x.join(y).keys.map(x => (x, None))).keys

答案 1 :(得分:2)

RDD上有intersection method,但只需要另外一个RDD:

def intersection(other: RDD[T]): RDD[T]

让我们根据这个实现你想要的方法。

def intersectRDDs[T](rdds: Seq[RDD[T]]): RDD[T] = {
  rdds.reduce { case (left, right) => left.intersection(right) 
}

如果您已经查看过Spark连接的实现,可以先将最大的RDD放在首位来优化执行:

def intersectRDDs[T](rdds: Seq[RDD[T]]): RDD[T] = {
  rdds.sortBy(rdd => -1 * rdd.partitions.length)
    .reduce { case (left, right) => left.intersection(right) 
}
编辑:看起来我误解了你的例子:你的文字看起来像是在搜索rdd.union的逆行为,但你的例子暗示你想要按键相交。我的答案没有解决这个问题。