下面这段代码是应该找到每密钥的平均使用combineByKey():CombineBy重点星火方法
val result = input.combineByKey(
(v) => (v, 1),
(acc: (Int, Int), v) => (acc._1 + v, acc._2 + 1),
(acc1: (Int, Int), acc2: (Int, Int)) => (acc1._1 + acc2._1, acc1._2 + acc2._2)).
map{ case (key, value) => (key, value._1/value._2.toFloat) }
result.collectAsMap().map(println(_))
我上面的方法的执行混乱。假设我们有数据集
((1,1), (1,3), (2,4), (2,3), (3,1))
。
所以combineByKey的执行将是这个样子?:
1)首先,它会创建一个累加器(1,1)
。
2)然后,当它遇到一个具有相同键(1)的元组时,它会将键值添加到一起?因此,当遇到(1,3)
时,密钥1的新累加器将看起来像(2,2)
。由于它添加了(1,1) and (1,3)
的密钥,并且由于有两个元组和密钥1,所以它将在(2,2)
中放置一个2(在右侧)。
3)然后它将继续为所有相同的密钥执行此操作。
4)然后最后它将从每个分区获取所有累加器,并将键(元组左侧)和发生次数(元组右侧)添加到一个元组中为每个键。
对不起,如果这是有点关闭,我仍然习惯于函数式编程方法!
哦,你指出了什么让我感到困惑,事实上,关键和价值都是数字!非常感谢您的详细解释,现在有道理! – LP496
也只是为了澄清它在最后一次“从每个分区获取所有累加器并将值(元组左侧)和发生次数(元组右侧)添加到每个键一个元组“。它知道每个键值对来自不同分区的哪个键。因此,让我们从分区1和2分别获得关键字1的(5,4)和(3,2)。和(3,4)和(4,5)分别为关键2。所以spark会知道将key 1元组和key 2元组合在一起? – LP496
是的,你的结构基本上是'(键:Int,(总和:Int,count; Int))' –