Pyspark中的AggregateByKey没有给出预期的输出

时间:2018-05-20 17:09:12

标签: pyspark rdd

我有一个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)]

我可以看到一个分区中的密钥只显示不给我预期的输出。我应该做些什么改变呢?

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)]