我有一组点(每个点都是文本文件中的一行),我在Spark的分区之间传播。
我使用mapPartitions操作,这导致我在每个分区中的一半点(并不重要,为什么以及如何)。
现在,我希望按对合并分区,因此分区#1和#2将是合并分区,分区#3和#4将是第二个合并分区,因此只有一个。
我将继续运行mapPartitions,直到我只剩下几个分区。 我怎么能用Spark做到这一点?
这里的Hadoop模拟是我按对合并输出文件并再次运行tak。
我将再次尝试澄清它:在运行mapPartitions后,我有x个分区, 我想成对合并它们,所以我会有x / 2分区并再次运行mapPartitions等等。
答案 0 :(得分:2)
使用treeAggregate
作为这样的模型应该可以解决这个问题:
from math import log
def binaryReduce(rdd, f):
assert log(rdd.getNumPartitions(), 2) % 1 == 0
def mapPartition(i, iter):
i = i / 2
for x in iter:
yield i, x
while rdd.getNumPartitions() != 1:
rdd = (rdd
.mapPartitionsWithIndex(mapPartition)
.reduceByKey(f, rdd.getNumPartitions() / 2)
.values())
return rdd.first()
如果您更喜欢更明确的方法,请始终保持分区编号:
def binaryReduce(rdd, f):
assert log(rdd.getNumPartitions(), 2) % 1 == 0
def initPartition(i, iter):
for x in iter:
yield i, x
rdd = rdd.mapPartitionsWithIndex(initPartition)
while rdd.getNumPartitions() != 1:
rdd = (rdd
.reduceByKey(f)
.map(lambda x: (x[0] / 2, x[1]))
.partitionBy(rdd.getNumPartitions() / 2))
return rdd.values().reduce(f)
对于Python 3.0+,请务必将/
替换为//
。
答案 1 :(得分:1)
这个问题非常模糊。 如果我做对了,你可以在将数据映射到(键,值)之后尝试使用reduceByKey。
(http://spark.apache.org/docs/latest/programming-guide.html#parallelized-collections)
希望这有帮助。
编辑:你应该使用mapPartitionsWithIndex(func)和func必须是类型(Int,Iterator)=>迭代器。