简单介绍

combineByKey()是最通用的对key-value型rdd进行聚集操作的聚集函数(aggregation function)。类似于aggregate(),combineByKey()允许用户返回值的类型与输入不一致。

其定义如下,我们可以根据这个形式来分别定义createCombiner、mergeValue和mergeCombiners三个函数:

def combineByKey[C](
  createCombiner: V => C, ##A
  mergeValue: (C, V) => C, ##B
  mergeCombiners: (C, C) => C,##C 
  partitioner: Partitioner,   
  mapSideCombine: Boolean = true,
  serializer: Serializer = null

)

自定义combineByKey

以实现一个计算平均值的功能为例来分别说明createCombiner、mergeValue和mergeCombiners三个函数的作用和定义方法。

##A createCombiner(value)

createCombiner: V => C ,这个函数把当前rdd中的值(value)作为参数,此时我们可以对其做些附加操作(类型转换)并把它返回 (这一步类似于初始化操作,分区内操作)

def createCombiner(value):

   (value, 1)

##B mergeValue(acc, value)

mergeValue: (C, V) => C,该函数把元素V合并到之前的元素C(createCombiner)上 (每个分区内合并)

def mergeValue(acc, value):
# 注意,这里的acc即为createCombiner产生的C。
# 这里,用acc[0]表明为acc这个元组中的第一个元素,在scala中acc._1表示
  (acc[0]+value, acc[1]+1)
###C   mergeCombiners: (acc1, acc2)

mergeCombiners: (C, C) => C,该函数把2个元素C合并 (此函数作用范围在rdd的不同分区间内,跨分区合并)

def mergeCombiners(acc1, acc2):

# 注意,到这一步,表明这个rdd的每条数据都已经被###A和###B捕获匹配完毕

   (acc1[0]+acc2[0], acc1[1]+acc2[1])

案例:

如图,有两个分区,key-value(类别-数量)形式也清楚,我们想知道coffee的平均数量和panda的平均数量。以scala形式写法如下:

val init_data = Array(("coffee", 1), ("coffee", 2), ("panda", 3), ("coffee", 9))
val data = sc.parallelize(init_data) # 两个分区
type MVType = (Int, Int) //定义一个元组类型
data.combineByKey(
   score => (1, score), # createCombiner函数
   (c: MVType, newScore) => (c._1 + 1, c._2 + newScore), # mergeValue函数
   (c1: MVType, c2: MVType) => (c1._1 + c2._1, c1._2 + c2._2) # mergeCombiners函数
).map { case (key, value) => (key, value._2/ value._1) }.map(println(_))

分析:

Partition 1 trace:
(coffee, 1) => new key
accumulators[coffee] = createCombiner(1)
得到:(coffee, (1, 1))
(coffee, 2) => existing key
accumulators[coffee] = mergeValue(accumulators[coffee], 2)
得到:(coffee, (2, 3))
显然(panda, 3) => new key,调用createCombiner方法。
得到:(panda, (1, 3))

Partition 2 trace:
(coffee, 9) => new key
accumulators[coffee] = createCombiner(9)
得到:(coffee, (1, 9))

接下来,mergeCombiners来合并分区:

Merge Partitions
mergeCombiners(partition1.accumulators[coffee], partition2.accumulators[coffee])
得到:(coffee, (3,12))

---------------------------------------------细心看 反复看 不然是假懂--------------------------------

讲明白combineByKey()算子,不是谈源码的更多相关文章

  1. sobel算子原理及opencv源码实现

    sobel算子原理及opencv源码实现 简要描述 sobel算子主要用于获得数字图像的一阶梯度,常见的应用和物理意义是边缘检测. 原理 算子使用两个33的矩阵(图1)算子使用两个33的矩阵(图1)去 ...

  2. 手把手教你使用LabVIEW人工智能视觉工具包快速实现传统Opencv算子的调用(含源码)

    前言 今天我们一起来使用LabVIEW AI视觉工具包快速实现图像的滤波与增强:图像灰度处理:阈值处理与设定:二值化处理:边缘提取与特征提取等基本操作.工具包的安装与下载方法可见之前的博客. 一.图像 ...

  3. 阿里P7终于讲完了JDK+Spring+mybatis+Dubbo+SpringMvc+Netty源码

    前言 这里普及一下,每个公司都有职别定级系统,阿里也是,技术岗以 P 定级,一般校招 P5, 社招 P6 起.其实阅读源码也是有很多诀窍的,这里分享几点心得: 首先要会用.你要知道这个库是干什么的,掌 ...

  4. cache2go源码最后一讲 - examples

    先看一下我们讲到哪里了: cache2go的源码前面我们已经讲完了cacheitem和cachetable的实现,今天cahce和examples会一起讲完~ 1.cache.go源码 ​      ...

  5. LinqToDB 源码分析——DataContext类

    LinqToDB框架是一个轻量级的ORM框架.当然,功能上来讲一定比不上Entity Framework的强大.但是在使用上总让笔者感觉有一点Entity Framework的影子.笔者想过可能的原因 ...

  6. 详解SpringMVC中Controller的方法中参数的工作原理[附带源码分析]

    目录 前言 现象 源码分析 HandlerMethodArgumentResolver与HandlerMethodReturnValueHandler接口介绍 HandlerMethodArgumen ...

  7. HashMap 源码详细分析(JDK1.8)

    一.概述 本篇文章我们来聊聊大家日常开发中常用的一个集合类 - HashMap.HashMap 最早出现在 JDK 1.2中,底层基于散列算法实现.HashMap 允许 null 键和 null 值, ...

  8. 深入出不来nodejs源码-流程总览

    花了差不多两周时间过了下primer C++5th,完成了<C++从入门到精通>.(手动滑稽) 这两天看了下node源码的一些入口方法,其实还是比较懵逼的,语法倒不是难点,主要是大量的宏造 ...

  9. 【MVC - 参数原理】详解SpringMVC中Controller的方法中参数的工作原理[附带源码分析]

    前言 SpringMVC是目前主流的Web MVC框架之一. 如果有同学对它不熟悉,那么请参考它的入门blog:http://www.cnblogs.com/fangjian0423/p/spring ...

随机推荐

  1. ISO文件怎么安装

    iso是光盘映像文件,打开iso文件有几种方法:1.使用光盘映像工具软件或者虚拟光驱才能打开iso文件.像软碟通(UItraISO)就是一个很好的光盘映像工具软件,使用它就可以打开iso文件,提取里面 ...

  2. OpenCV——PS 滤镜算法之极坐标变换到平面坐标

    // define head function #ifndef PS_ALGORITHM_H_INCLUDED #define PS_ALGORITHM_H_INCLUDED #include < ...

  3. Pycharm用鼠标滚轮控制字体大小的

    Pycharm用鼠标滚轮控制字体大小的   一.pycharm字体放大的设置 File —> setting —> Keymap —>在搜寻框中输入:increase —> I ...

  4. Behave + Selenium(Python)一:

    Behave 介绍:(来自T先生) 最近一个项目用了behave来做测试,因为之前没有接触过,所以写下最近的心得总结. 做自动化的人估计对selenium已经不是很陌生了,但是对于Behave工具,估 ...

  5. Advanced R之词汇表

    转载请注明出处:http://www.cnblogs.com/lizichao/p/4800513.html 词汇表 想要玩得转R,重要的一点是有一个好的工作词汇表.以下是我认为的一个好的词汇表.你不 ...

  6. Excel添加水印

    Excel添加水印[源码下载] 步骤一:根据生成图片的类创建水印图片 步骤二: 代码在Excel中根据第一行获取sheet的列数[sheet.getRow(0).getLastCellNum() ], ...

  7. 使用MeshLab的技巧总结(自己原创总结)

    1.放大点的显示,Alt+wheel,即按住Alt键后使用鼠标滑轮改变点的显示大小.

  8. 结合webpack 一步一步实现懒加载的国际化简易版方案

    想法来源于工作需求,最后倒腾出一个国际化工作流,期望是这样的: 1. 自动化处理国际化文案(表现为转义翻译人员给到的文件处理成技术人员所识别的文件) 2. 转化后的国际化文件能够按需加载,实现懒加载的 ...

  9. 实现prim算法

    如下找出该图的最小生成树 prim算法是求解该类问题的一种经典算法 Prim算法的基本思路:将图中的所有的顶点分为两类:树顶点(已经被选入生成树的顶点)和非树顶点(还未被选入生成树的顶点).首先选择任 ...

  10. poj3186(区间dp)

    题目链接:http://poj.org/problem?id=3186 题意:给一行n个数,每次可以取出行首或者行末的数,如果第ai是第i次取出的,可以得到ai*i的收益,求最大的总收益: 思路:区间 ...