如何在pyspark中有效地向RDD添加新密钥

时间:2016-06-13 11:56:00

标签: python apache-spark pyspark rdd

我有两种RDD格式,第一种格式为((provider, currency), value),密钥为(provider, currency),第二种格式为(provider, value),其中密钥为provider

我想要做的是将RDD A (provider, value)格式转换为((provider, currency), value)。我有一个 B ((provider, currency), value) RDD,我会拿钥匙。然后我将使用这些键扩展RDD A ,以便value RDD中的每个(provider, value)都会为新{{1}中的每个currency重复一次RDD。

如何以高效的方式完成,而不必收集()RDD并循环它们?

例如:

来自RDD A 的项目将是:

((provider, currency), value)

然后来自RDD B 的一些键将是

(1773570, 4135.7998046875)

输出RDD应为:

[(1773570, 'EUR/USD'), (1773570, 'GBP/USD'), (1773570, 'USD/CAD')]

可能的解决方案是:

[((1773570, 'EUR/USD'), 4135.7998046875), ((1773570, 'GBP/USD'), 4135.7998046875), ((1773570, 'USD/CAD'), 4135.7998046875)]

在这里,我使用def get_keys(rdd): return rdd.map(lambda item: (item[0])).collect() def canonicalize_keys(sc, feature, keys): def transform(item, keys): return [ ((item[0], currency_pair), item[1]) for provider_id, currency_pair in keys if provider_id == item[0]] return sc.parallelize(feature .map(lambda item: transform(item, keys)) .reduce(lambda a, b: a + b)) 从RDD B 获取密钥,然后我使用这些密钥转换RDD A 。这里的问题是,如果我有很多currency_pairs,我会从JVM获得OutOfMemoryErrors。

1 个答案:

答案 0 :(得分:4)

试试这个: 鉴于Brdd = RDD[((provider, currency), value)]Ardd,您要加入BrddnewRDD,以使RDD[((provider, currency), value)]的格式为valueArdd指的是从newRDD = Ardd.join(Brdd.map(lambda x: x[0])).map(lambda x: ((x[0], x[1][1]), x[1][0])) 找到的值。

要做到这一点,我们所做的就是:

One Line Solution:

Brdd

逐步说明:

  1. Brdd_keys = Brdd.map(lambda x: x[0])获取密钥:RDD[(provider, currency)]。输出格式为:AB = Ardd.join(Brdd_keys)

  2. 加入Ardd和Brdd_keys:RDD[(provider, (value, currency))]。输出格式为:newRDD = AB.map(lambda x: ((x[0], x[1][1]), x[1][0]))

  3. 映射到最终形式:RDD[((provider, currency), value)]。输出现在具有@screen-sm

  4. 形式