我只是想找到与特定键相关的所有值的平均值,以下是我的程序:
from pyspark import SparkContext,SparkConf
conf = SparkConf().setAppName("averages").setMaster("local")
sc = SparkContext(conf=conf)
file_rdd = sc.textFile("C:\spark_programs\python programs\input")
vals_rdd = file_rdd.map(lambda x:(x.split(" ")[0],int(x.split(" ")[2])))
print type(vals_rdd)
pairs_rdd = vals_rdd.reduceByKey(lambda x,y:(x+y)/2)
for line in pairs_rdd.collect():
print line
以下是输入数据:
a hyd 2
b hyd 2
c blr 3
d chn 4
b hyd 5
当我运行程序时,我得到的输出如下:
(u'a', 2)
(u'c', 3)
(u'b', 3) -- I could see only got b's value getting averaged.
(u'd', 4)
除了b值之外,所有值都没有被平均。为什么会这样?为什么没有a,c,d值平均值?
答案 0 :(得分:1)
使用关联和可交换 reduce函数合并每个键的值。
您通过的功能并不满足这些要求。特别是它不是关联的:
f = lambda x,y:(x + y) / 2
f(1, f(2, 3))
## 1.75
f(f(1, 2), 3)
## 2.25
因此,它不适用于您的情况,也不会对这些值进行平均。
值不是平均值。为什么会这样?
除了上面解释的基本缺陷外,每个剩余密钥只有一个值,因此根本没有理由调用合并功能。
我只是想找到与特定键相关联的平均值
只需使用DataFrames
:
vals_rdd.toDF().groupBy("_1").avg()
虽然你可以use aggregateByKey
with StatCounter
(数值稳定)或map
-> reduceByKey
-> map
(数值不稳定)。
此外,我强烈建议您阅读reduceByKey: How does it work internally?的优秀答案。