Spark:如何在map(python)中生成多个元素?

时间:2016-05-02 21:00:54

标签: python apache-spark pyspark

我的数据包含键和值列表。     rdd =(Key,[Value])

我想要的是:

rdd.map(lambda pair: func(pair))

其中函数为每对返回几个(Value,New_value)。注意,New_value也依赖于Key!

所以,简单地说,在

上使用.map()之后
(key1, [Value1, Value2])
(key2, [Value3, Value4, Value5])

我想收到:

(Value1, NewValue1)
(Value2, NewValue2)
(Value3, NewValue3)
(Value4, NewValue4)
(Value5, NewValue5)

如何在PySpark中制作?

2 个答案:

答案 0 :(得分:1)

让func成为连接的键值。

def func(kv):
    return '-'.join(kv)

您希望将所有列表展平为(键,值)对

rdd.flatMap(lambda kv: ((kv[0], v) for v in kv[1]))

然后将func映射到所有对,同时将初始值保留为结果的一部分

 map(lambda kv: (kv[1], func(kv)))

总之,

rdd.flatMap(lambda kv: ((kv[0], v) for v in kv[1])).map(lambda kv: (kv[1], func(kv)))

实施例

>>> rdd = sc.parallelize([('k1', ['v1', 'v2']), ('k2', ['v3','v4','v5'])])
>>> rdd.flatMap(lambda kv: ((kv[0], v) for v in kv[1])).map(lambda kv: (kv[1], func(kv))).collect()
[('v1', 'k1-v1'),
 ('v2', 'k1-v2'),
 ('v3', 'k2-v3'),
 ('v4', 'k2-v4'),
 ('v5', 'k2-v5')]

答案 1 :(得分:0)

我发现使用yield

与@ cricket_007解决方案不同
>>> rdd = sc.parallelize([('k1', ['v1', 'v2']), ('k2', ['v3','v4','v5'])])
>>> def func(kv):
...     for v in kv[1]:
...         yield (v, kv[0] + '-' + v)
>>>rdd.flatMap(lambda kv: func(kv)).collect()
[('v1', 'k1-v1'), 
 ('v2', 'k1-v2'), 
 ('v3', 'k2-v3'), 
 ('v4', 'k2-v4'), 
 ('v5', 'k2-v5')]