假设我有以下RDD:
alist = [('a',[['1',2]]),('b',[['2',3]]),('b',[['8',5]]),('b',[['8',5]]),('c',[['4',22]]),('a',[['5',22]])]
anRDD = sc.parallelize(alist)
我的任务是从每个字符串字母获取具有最高int值的列表(列表的索引1)。如果有大量数据和许多不同的密钥(字符串字母),建议采用以下哪种方法?
方法1:
import operator
def sortAndTake(alistoflists):
alistoflists.sort(key=operator.itemgetter(1),reverse=True)
return alistoflists[0]
reducedRDD = anRDD.reduceByKey(lambda a,b:a+b)
finalRDD = reducedRDD.map(lambda x: (x[0],sortAndTake(x[1])))
finalRDD.collect()
方法2:
def partitioner(n):
def partitioner_(x):
return portable_hash(x[0]) % n
return partitioner_
def sortIterator(iterator):
oldKey = None
cnt = 0
for item in iterator:
if item[0] != oldKey:
oldKey = item[0]
yield item
partitioned = anRDD.keyBy(lambda kv:(kv[0],kv[1][0][1]))
partitioned.repartitionAndSortWithinPartitions(
numPartitions=2,
partitionFunc=partitioner(2),ascending=False)
.map(lambda x: x[1])
.mapPartitions(sortIterator)
(方法2的灵感来自我之前提出的问题的接受答案(通过零323):Using repartitionAndSortWithinPartitions
)
根据我对第一种方法的理解,如果我们得到了一个巨大的不同键值,reduceByKey
中的工作人员之间会有很多改组,这可能会使方法2变得更快(我不确定是否相同在方法2中使用repartitionAndSortWithinPartitions
时发生。
有什么见解?谢谢:))
答案 0 :(得分:2)
我的任务是从每个字符串字母获取具有最高int值的列表(列表的索引1)。
如果是这种情况,两种方法效率都很低。而只是reduceByKey
与max
:
from operator import itemgetter
from functools import partial
anRDD.mapValues(itemgetter(0)).reduceByKey(partial(max, key=itemgetter(1)))
关于两种提议的方法:
groupByKey
。