我如何计算Spark RDD的平均值?

时间:2017-09-12 08:17:06

标签: scala apache-spark rdd

我遇到Spark Scala的问题,我想从Rdd数据中计算平均值,我创建了一个像这样的新RDD,

[(2,110),(2,130),(2,120),(3,200),(3,206),(3,206),(4,150),(4,160),(4,170)]

我想像这样算数,

[(2,(110+130+120)/3),(3,(200+206+206)/3),(4,(150+160+170)/3)]

然后,得到这样的结果,

   [(2,120),(3,204),(4,160)]

如何使用RDD中的scala执行此操作? 我使用spark版本1.6

3 个答案:

答案 0 :(得分:3)

你可以使用aggregateByKey。

val rdd = sc.parallelize(Seq((2,110),(2,130),(2,120),(3,200),(3,206),(3,206),(4,150),(4,160),(4,170)))
val agg_rdd = rdd.aggregateByKey((0,0))((acc, value) => (acc._1 + value, acc._2 + 1),(acc1, acc2) => (acc1._1 + acc2._1, acc1._2 + acc2._2))
val sum = agg_rdd.mapValues(x => (x._1/x._2))
sum.collect

答案 1 :(得分:2)

在这种情况下你可以使用groupByKey。像这样

val rdd = spark.sparkContext.parallelize(List((2,110),(2,130),(2,120),(3,200),(3,206),(3,206),(4,150),(4,160),(4,170)))
val processedRDD = rdd.groupByKey.mapValues{iterator => iterator.sum / iterator.size}
processedRDD.collect.toList

在此,groupByKey将返回RDD[(Int, Iterator[Int])],然后您只需在Iterator上应用平均操作

希望这适合你

由于

答案 2 :(得分:1)

您可以使用.combineByKey()来计算平均值:

val data = sc.parallelize(Seq((2,110),(2,130),(2,120),(3,200),(3,206),(3,206),(4,150),(4,160),(4,170)))

val sumCountPair = data.combineByKey((x: Int) => (x.toDouble,1),
                                     (pair1: (Double, Int), x: Int) => (pair1._1 + x, pair1._2 + 1), 
                                     (pair1: (Double, Int), pair2: (Double, Int)) => (pair1._1 + pair2._1, pair1._2 + pair2._2))

val average = sumCountPair.map(x => (x._1, (x._2._1/x._2._2)))
average.collect()

此处sumCountPair返回RDD[(Int, (Double, Int))]类型,表示:(Key, (SumValue, CountValue))。下一步只是将sum除以计数并返回(Key, AverageValue)