我正在编写一个 Spark 应用程序,并希望将一组键值对 (K, V1), (K, V2), ..., (K, Vn)
组合成一个键-多值对(K, [V1, V2, ..., Vn])
。我觉得我应该能够使用具有某种 flavor 的 reduceByKey
函数来做到这一点:
My_KMV = My_KV.reduce(lambda a, b: a.append([b]))
发生这种情况时我得到的错误是:
'NoneType' object has no attribue 'append'.
我的键是整数,值 V1,...,Vn 是元组。我的目标是使用键和值列表(元组)创建一对。
最佳答案
Map 和 ReduceByKey
reduce
的输入类型和输出类型必须相同,所以如果你想聚合一个列表,你必须map
输入到列表。然后将这些列表合并为一个列表。
组合列表
您需要一种将列表合并为一个列表的方法。 Python 提供了一些 methods to combine lists .
append
修改第一个列表,并且总是返回 None
。
x = [1, 2, 3]
x.append([4, 5])
# x is [1, 2, 3, [4, 5]]
extend
做同样的事情,但解开列表:
x = [1, 2, 3]
x.extend([4, 5])
# x is [1, 2, 3, 4, 5]
这两种方法都返回 None
,但您需要一个返回组合列表的方法,因此只需 use the plus sign .
x = [1, 2, 3] + [4, 5]
# x is [1, 2, 3, 4, 5]
Spark
file = spark.textFile("hdfs://...")
counts = file.flatMap(lambda line: line.split(" ")) \
.map(lambda actor: (actor.split(",")[0], actor)) \
# transform each value into a list
.map(lambda nameTuple: (nameTuple[0], [ nameTuple[1] ])) \
# combine lists: ([1,2,3] + [4,5]) becomes [1,2,3,4,5]
.reduceByKey(lambda a, b: a + b)
组合键
也可以用combineByKey
来解决这个问题,它在内部用于实现reduceByKey
,但它更复杂,"using one of the specialized per-key combiners in Spark can be much faster" .对于上面的解决方案,您的用例已经足够简单了。
GroupByKey
也可以使用 groupByKey
, but it reduces parallelization 来解决这个问题因此对于大数据集可能会慢得多。
关于python - 使用 Apache Spark 将键值对缩减为键列表对,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27002161/