我有一个RDD,它有2个分区和键值对数据作为值:
rdd5.glom().collect()
[[(u'hive',1),(u'python',1),(u'spark',1),(u'hive',1), (u'spark',1),(u'python',1)],[(u'spark',1),(u'java',1), (u'java',1),(u'spark',1)]]
当我执行aggregateByKey
rdd6=rdd5.aggregateByKey((0,0), lambda acc,val: (acc[0]+1,acc[1]+val), lambda acc1,acc2 : (acc1[1]+acc2[1])/acc1[0]+acc2[0])
它没有给我预期的结果:
输出:
[(u'python',(2,2)),(u'spark',1),(u'java',(2,2)),(u'hive',(2, 2))]
预期:
[(u'python',1),(u'spark',1),(u'java',1),(u'hive',1)]
我可以看到一个分区中的密钥只显示不给我预期的输出。我应该做些什么改变呢?
答案 0 :(得分:0)
好的以下是使用reduceByKey和aggregateByKey执行此操作的方法。
你对aggregateByKey的问题是最后一个函数负责添加两个累加器。它必须返回与所有其他函数相同的结构,以便在添加另一个新累加器时(从另一个分区)它将再次起作用。
与combineByKey非常相似,请参阅here。
rdd = sc.parallelize([(u'hive', 1), (u'python', 1), (u'spark', 1),\
(u'hive', 1), (u'spark', 1), (u'python', 1), (u'spark', 1), (u'java', 1), (u'java', 1), (u'spark', 1)])
print rdd.aggregateByKey( (0, 0), lambda acc, val: (acc[0] + 1,acc[1] + val),\
lambda acc1, acc2 : (acc1[0] + acc2[0], acc1[1] + acc2[1])).collect()
print rdd.mapValues(lambda x: (1, x)).reduceByKey(lambda x, y: (x[0] + y[0], x[1] + y[1])).collect()
[(你' spark',(4,4)),(你' java',(2,2)),(你' hive',(2 ,2)),(你' python', (2,2))]
[(你' spark',(4,4)),(你' java',(2,2)),(你' hive',(2 ,2)),(你' python', (2,2))]
如果您尝试对值进行平均,可以在最后添加另一个mapValues,如下所示:
print rdd.aggregateByKey( (0, 0),\
lambda acc, val: (acc[0] + 1,acc[1] + val),\
lambda acc1, acc2 : (acc1[0] + acc2[0], acc1[1] + acc2[1]))\
.mapValues(lambda x: x[1] * 1.0 / x[0])\
.collect()
[(你' spark',1.0),(你' java',1.0),(你' hive',1.0),(你' python&# 39;,1.0)]