RDD.aggregate操作如何工作(即如何理解参数)?

时间:2017-04-07 06:06:05

标签: scala apache-spark

任何人都可以详细解释下面如何在spark中产生agrregate行为产生(9,4)

的结果
val rdd = sc.parallelize(List(1,2,3,3))

rdd.aggregate((0, 0))
((x, y) =>
(x._1 + y, x._2 + 1),
(x, y) =>
(x._1 + y._1, x._2 + y._2))

res : (9,4)

3 个答案:

答案 0 :(得分:3)

基本上聚合说:我们想要一个元组(a,b),其中a是所有元素的总和,b是它们的计数。

这是通过初始化为(0,0)完成的,然后我们有两个函数:

  • 第一个函数只是在我们一次得到一个元素时进行求和,即通过将值添加到第一个元素并将1(count)加到第二个元素来从单个元素更新元组。

  • 第二个函数合并两个结果,因此它只是元素添加

让我们考虑输入数据的示例:

假设1,2在分区1中,3,3在分区3中。

分区1计算

分区1将以(0,0)开头。

然后第一个功能开始工作。

当我们添加一个(1,1)时。第一个元素是sum(0 + y,其中y是1),第二个元素是count(0 + 1)。

现在我们加2,所以得到(1 + 2,1 + 1)=(3,2)。再次,第一个元素是我们到目前为止看到的值的总和,第二个元素是它们的计数。

分区2计算

在第二个分区上,我们再次以(0,0)开始,然后从第一个分区得到(3,1),从第二个分区得到(6,2)。

合并结果

现在第二个功能合并两个: 我们通过将两个元素相加并得到(9,4)

来合并(3,2)和(6,2)

答案 1 :(得分:1)

这是 Spark 2.1.0 (这应该不重要,但是......)

转到the official documentation of aggregate(又名 scaladoc )并阅读:

  

使用给定的组合函数和中性"零值"聚合每个分区的元素,然后聚合所有分区的结果。此函数可以返回与此RDD,T的类型不同的结果类型U。因此,我们需要一个操作将T合并到U中,并且需要一个操作来合并两个U,如scala.TraversableOnce 。允许这两个函数修改并返回它们的第一个参数,而不是创建一个新的U来避免内存分配。

签名如下(删除隐含参数并不特别有趣):

aggregate[U](zeroValue: U)(seqOp: (U, T) ⇒ U, combOp: (U, U) ⇒ U): U

scaladoc说:

  

zeroValue seqOp运算符的每个分区的累积结果的初始值,以及combOp运算符的不同分区的组合结果的初始值 - 这通常是中性元素(例如,列表连接为Nil,或者求和为0)

在您的情况下,zeroValue(0, 0)

  

seqOp 用于在分区中累积结果的运算符

在您的情况下,seqOp(x, y) => (x._1 + y, x._2 + 1),这是一个接受两对的函数,不幸名为xy(我称之为{{1}至少和p1至少使用模式匹配和部分函数,​​即p2)。

鉴于您已获得case ((x1, y1), (x2, y2)) => ...个分区(可以使用n查看),rdd.getNumPartition将被称为seqOp次。

scaladoc说:

  

combOp 用于合并来自不同分区的结果的关联运算符

这意味着n将结合combOp的所有结果并应用该函数:

seqOp

它再次写得太糟糕,所以你看得太多了,我甚至打电话给一个噪音。我按如下方式编写函数:

(x, y) => (x._1 + y._1, x._2 + y._2)

按照类型并给出正确的名称,最终Scala中的所有内容变得更加容易; - )

答案 2 :(得分:0)

让我们变得简单

情况1:没有分区,只是独立存在( seqOp )。专注于(x,y)=> (x._1 + y,x._2 + 1),忽略分区。

{1,2,3,3}
            x._1    y      x._2     
(0+1,0+1)   0       1      0
(1+2,1+1)   1       2      1
(3+3,2+1)   3       3      2
(6+3,3+1)   6       3      3
Result:(9,4)

情况2:具有分区,假设2个分区( combOp ){1,2},{3,3}。专注于 (x,y)=> (x._1 + y,x._2 +1),

(x,y)=> (x._1 + y._1,x._2 + y._2))

{1,2}
            x._1    y      x._2     
(0+1,0+1)   0       1      0
(1+2,1+1)   1       2      1
Result1: (3,2)

{3,3}
            x._1    y      x._2  
(0+3,0+1)   0       3      0
(3+3,1+1)   3       3      1
Result2: (6,2)

Final result:(9,4)