如何在Scala中使用聚合工作?

时间:2017-01-24 17:17:28

标签: scala

我一直在读一本火花书,这个例子来自书中

input = List(1,2,3,4,5,6)
val result = input.aggregate((0, 0))(
(acc, value) => (acc._1 + value, acc._2 + 1),
(acc1, acc2) => (acc1._1 + acc2._1, acc1._2 + acc2._2))
val avg = result._1 / result._2.toDouble

我试图理解这是如何工作的,每一步的_1和_2是什么

(0,0)是种子值或初始值 这个列表被分成了sep rdd 让我们说rdd1包含List(1,2) 循环浏览此列表

(acc,value)
acc = ???在循环的每次迭代期间 值= ???在循环的每次迭代期间

(acc,value)=> (acc._1 + value,acc._2 + 1) 在List(1,2)的第一次迭代期间,acc._1和_2以及值

的值是多少

(acc1,acc2)=> (acc1._1 + acc2._1,acc1._2 + acc2._2)) acc1(对于1,2)类似于3,2而acc2(对于3,4)是7,2 此函数添加3 + 7和2 + 2 = 10,4并将此值添加到下一组

亲爱的善良助手,

请不要使用scala中使用的术语,我已经读过它并且不理解它因此来寻求帮助。

对于List(1,2),在列表的第一次迭代期间acc._1和acc._2的值是什么,在该迭代期间,'value'的值是什么,在第二次迭代期间什么是他们的价值观?

2 个答案:

答案 0 :(得分:0)

aggregate通过接受两个函数来工作,一个函数组合了分区中的值,另一个组合了分区。

第一个函数(单个分区的函数)可以更清楚地写为

((sum, count), value) => (sum + value, count + 1)

第二个功能(组合分区)可以写成

((partition1Sum, partition1Count), (partition2Sum, partition2Count)) =>
    (partition1Sum + partition2Sum, partition1Count + partition2Count)


关于元组符号的注释:

在Scala中(a, b, c)._1 == a(a, b, c)._2 == b等等。 _n为您提供元组的第n个元素。

答案 1 :(得分:0)

聚合函数的第一个参数采用初始值,在此示例中是一个元组(0,0),然后下一个参数是seqop,它是一个函数(B, A) => A,在您的示例中它会(Tuple, Int) => Tuple

这里发生的是这个函数逐个应用于列表的每个参数。元组实际上在列表的总和左侧,在右侧保存到目前为止传递的列表的数量。聚合函数的结果是(21, 6)

附注:Scala中TraversableOnce的实现并未真正使用combop参数,在此示例中为(acc1, acc2) => (acc1._1 + acc2._1, acc1._2 + acc2._2))所以在这种情况下您可以忽略它。如果您熟悉Scala,则执行的代码为:

input.foldLeft((0, 0))((acc, value) => (acc._1 + value, acc._2 + 1))