combineByKey:
Generic function to combine the elements for each key using a custom set of aggregation functions.
概述
.combineByKey
方法是基于键进行聚合的函数(大多数基于键聚合的函数都是用它实现的),所以这个方法还是挺重要的。
我们设聚合前Pair RDD的键值对格式为:键为K,键值格式为V;而聚合后,键格式不便,键值格式为C。
combineByKey
函数的定义为:
combineByKey(createCombiner, mergeValue, mergeCombiners, numPartitions=None, partitionFunc=<function portable_hash at 0x7fc35dbc8e60>)
该函数的参数主要为前三个:
- createCombiner
- mergeValue
- mergeCombiners
示意图如下:
一个例子
还是先看一个例子,暂时看不懂可以先看下面再回来。
>>> test = sc.parallelize([('panda', (1,2)), ('pink',(7,2)), ('pirate',(3,1))])
>>> xx = test.combineByKey((lambda x : (x,1)),
... (lambda x,y: (x[0] + y, x[1]+ 1)),
... (lambda x,y : (x[0] + y[0], x[1] + y[1])) )
>>> xx.collect()
[('coffee', (3, 2)), ('panda', (3, 1))]
这里,三个参数分别用了3个lambda表达式代替,分别为:
- createCombiner : lambda x : (x,1)
- mergeValue : lambda x , y : (x[0] + y , x[1] + 1 )
- mergeCombiners : lambda x , y : (x[0] + y[0], x[1] + y[1])
下面解释这三个参数。
createCombiner
由于聚合操作会遍分区中所有的元素,因此每个元素(这里指的是键值对)的键只有两种情况:
- 以前没出现过
- 以前出现过
如果以前没出现过,则执行的是createCombiner
方法;否则执行mergeValue方法
,即:
.createCombiner()
会在新遇到的键对应的累加器中赋予初始值。
该函数在格式上是由 V -> C
的,在上面的例子里面,是由 整数类型 -> 二元元组类型,这个二元元组第二个元素为1。
mergeValue
对于已经出现过的键(key),调用mergeValue来进行聚合操作,对该键的累加器对应的当前值(C格式)于这个新的值(V格式)进行合并。
mergeCombiners
如果有两个或者更多的分区(这里的例子里没提到)都有对应同一个键的累加器,就需要使用用户提供的mergeCombiners()
方法将各个分区的结果(全是C格式)进行合并。