为什么在reduce中使用减法的结果不一致?

时间:2016-04-23 16:34:22

标签: scala apache-spark

鉴于以下内容:

val rdd = List(1,2,3)

我认为rdd.reduce((x,y) => (x - y))会返回-4(即(1-2)-3=-4),但会返回2

为什么?

3 个答案:

答案 0 :(得分:7)

从RDD源代码(和docs):

/**
* Reduces the elements of this RDD using the specified commutative and
* associative binary operator.
*/
def reduce(f: (T, T) => T): T

reduce是一个单调缩减,因此它假设函数是可交换关联,这意味着不能保证将它应用于元素的顺序。

显然,你的函数(x,y)=>(x-y)不是可交换的,也不是关联的。

在您的情况下,reduce可能是以这种方式应用的:

3 - (2 - 1) = 2

1 - (2 - 3) = 2

答案 1 :(得分:2)

您可以使用 v1 - (v2 + ... + vN)轻松替换减法 v1 - v2 - ... - vN ,因此您的代码可能看起来像

val v1 = 1
val values = Seq(2, 3)
val sum = sc.paralellize(values).reduce(_ + _)
val result = v1 - sum

答案 2 :(得分:1)

正如@TzachZohar所述,函数必须满足两个属性,以便并行计算是合理的;通过收集 rdd,reduce放松了函数中所需的属性,因此它产生了顺序(非并行)计算的结果,即

val rdd = sc.parallelize(1 to 3)

rdd.collect.reduce((x,y) => (x-y))
Int = -4