【问题标题】:trying to understand the reduceByKey() action's behaviour试图了解 reduceByKey() 操作的行为
【发布时间】:2017-10-01 21:58:55
【问题描述】:

我只想找到与特定键关联的所有值的平均值,下面是我的程序:

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 值不取平均值??

【问题讨论】:

    标签: python apache-spark


    【解决方案1】:

    reduceByKey is used to:

    使用关联和交换 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? 的精彩答案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多