有效的方法来reduceByKey忽略不在另一个RDD中的键?

时间:2018-04-11 15:12:27

标签: apache-spark pyspark

我在pyspark中有大量数据。格式是键值对,我需要执行reducebykey操作,但是忽略其键不在RDD中的所有数据,这些数据是有趣的'我也有的钥匙。

我在SO上找到了一个利用subtractbykey操作实现此目的的解决方案。它可以工作,但由于我的集群内存不足而导致崩溃。我无法通过调整设置来改变这一点,所以我希望这是一个更有效的解决方案。

这是我的解决方案适用于较小的数据集:

# The keys I'm interested in
edges = sc.parallelize([("a", "b"), ("b", "c"), ("a", "d")])
# Data containing both interesting and uninteresting stuff
data1 = sc.parallelize([(("a", "b"), [42]), (("a", "c"), [60]), (("a", "d"), [13, 37])])
data2 = sc.parallelize([(("a", "b"), [43]), (("b", "c"), [23, 24]), (("a", "c"), [13, 37])])
all_data = [data1, data2]

mask = edges.map(lambda t: (tuple(t), None))
rdds = []
for datum in all_data:
    combined = datum.reduceByKey(lambda a, b: a+b)
    unwanted = combined.subtractByKey(mask)
    wanted = combined.subtractByKey(unwanted)
    rdds.append(wanted)

edge_alltimes = sc.union(rdds).reduceByKey(lambda a,b: a+b)
edge_alltimes.collect()

根据需要,输出[((' a',' d'),[13,37]),((' a',&# 39; b'),[42,43]),((' b',' c'),[23,24])] (即,有趣的'关键元组的数据已合并,其余部分已被删除)。 我在几个RDD中拥有数据的原因是模仿我的集群上的行为,由于其大小,我无法同时加载所有数据。 任何帮助都会很棒。

1 个答案:

答案 0 :(得分:1)

加入示例。一个小缺点是你需要在加入之前有对的RDD,你需要在加入后删除额外的数据。

import org.apache.spark.{SparkConf, SparkContext}

object Main {

  val conf = new SparkConf().setAppName("myapp").setMaster("local[*]")
  val sc = new SparkContext(conf)

  def main(args: Array[String]): Unit = {

    val goodKeys = sc.parallelize(Seq(1, 2))
    val allData = sc.parallelize(Seq((1, "a"), (2, "b"), (3, "c")))


    val goodPairs = goodKeys.map(v => (v, 0))

    val goodData = allData.join(goodPairs).mapValues(p => p._1)

    goodData.collect().foreach(println)
  }
}

输出:

(1,a)
(2,b)