我已经阅读到reduce函数必须是可交换的和关联的。我应该如何编写函数以找到平均值,使其符合此要求?如果我将以下函数用于计算rdd的平均值,它将无法正确计算平均值。谁能解释我的功能出了什么问题?
我猜想它需要两个元素(例如1、2)并将函数应用于它们,例如(1 + 2)/ 2。然后将结果与下一个元素3相加,然后除以2等。
val rdd = sc.parallelize(1 to 100)
rdd.reduce((_ + _) / 2)
答案 0 :(得分:2)
rdd.reduce((_ + _)/ 2)
上述reduce
方法的平均计算存在一些问题:
placeholder
语法不能用作reduce((acc, x) => (acc + x) / 2)
的简写rdd.reduce((acc, x) => (acc + x) / 2)
将在每次迭代中产生integer division
(对于计算平均值肯定不正确) reduce
方法不会产生列表的平均值。例如:
List[Double](1, 2, 3).reduce((a, x) => (a + x) / 2)
--> (1.0 + 2.0) / 2 = 1.5
--> (1.5 + 3.0) / 2 = 2.25
Result: 2.25
而:
Average of List[Double](1, 2, 3) = 2.0
我应该如何编写[reduce]函数来找到平均值,使其符合此要求?
我不确定reduce
是否适合直接计算列表的平均值。您当然可以使用reduce(_ + _)
对列表求和,然后将总和除以其大小,例如:
rdd.reduce(_ + _) / rdd.count.toDouble
但是您可以简单地使用RDD的内置函数mean
:
rdd.mean
答案 1 :(得分:1)
您还可以使用PairRDD
来跟踪所有元素的总和以及元素计数。
val pair = sc.parallelize(1 to 100)
.map(x => (x, 1))
.reduce((x, y) => (x._1 + y._1, x._2 + y._2))
val mean = pair._1 / pair._2