[Spark] 关于函数 combineByKey

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

示意图如下:

combineByKey-illustrated

一个例子

还是先看一个例子,暂时看不懂可以先看下面再回来。

>>> 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方法,即:

Key-Value-Pair

.createCombiner()会在新遇到的键对应的累加器中赋予初始值。

该函数在格式上是由 V -> C 的,在上面的例子里面,是由 整数类型 -> 二元元组类型,这个二元元组第二个元素为1。

mergeValue

对于已经出现过的键(key),调用mergeValue来进行聚合操作,对该键的累加器对应的当前值(C格式)于这个新的值(V格式)进行合并。

mergeCombiners

如果有两个或者更多的分区(这里的例子里没提到)都有对应同一个键的累加器,就需要使用用户提供的mergeCombiners()方法将各个分区的结果(全是C格式)进行合并。

posted @ 2017-01-10 08:46  guoyunzhe  阅读(2859)  评论(0编辑  收藏  举报