我有两种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。
答案 0 :(得分:4)
试试这个:
鉴于Brdd = RDD[((provider, currency), value)]
和Ardd
,您要加入Brdd
和newRDD
,以使RDD[((provider, currency), value)]
的格式为value
。 Ardd
指的是从newRDD = Ardd.join(Brdd.map(lambda x: x[0])).map(lambda x: ((x[0], x[1][1]), x[1][0]))
找到的值。
要做到这一点,我们所做的就是:
One Line Solution:
Brdd
逐步说明:
从Brdd_keys = Brdd.map(lambda x: x[0])
获取密钥:RDD[(provider, currency)]
。输出格式为:AB = Ardd.join(Brdd_keys)
加入Ardd和Brdd_keys:RDD[(provider, (value, currency))]
。输出格式为:newRDD = AB.map(lambda x: ((x[0], x[1][1]), x[1][0]))
映射到最终形式:RDD[((provider, currency), value)]
。输出现在具有@screen-sm