Spark中的CombineKey()详解
CombineKey()是最常用的基于键进行聚合的函数,大多数基于键聚合的函数都是用它实现的。和aggregate()一样,CombineKey()可以让用户返回与输入数据的类型不同的返回值。要理解CombineKey()需要先理解它在数据处理时是如何处理每个元素的。由于CombineKey()会遍历分区中的所有元素,因此每个元素的键要么还没有遇到,要么就是和之前的额某个元素的键相同。
如果遇到的是一个新元素,CombineKey()会使用一个叫做createCombiner()的函数来创建那个键对应的累加器的初始值,需要注意的是,这一过程会在每个分区中第一次出现各个键时发生,而不是在整个RDD中第一次出现时发生。
如果这是一个在处理当前分区之前已经遇到的键,它会使用mergeValue()方法将该键的累加器对应的值与这个新的值进行合并。
由于每个分区都是独立处理的,因此对于同一个键可以有多个累加器。如果有两个或者更多的分区都有对应同一个键的累加器,就需要使用用户提供的mergeCombiners()方法将各个分区的结果进行合并。
如果已知数据在进行combineByKey() 时无法从map 端聚合中获益的话,可以禁用它。例如,由于聚合函数(追加到一个队列)无法在map 端聚合时节约任何空间,groupByKey() 就把它禁用了。如果希望禁用map 端组合,就需要指定分区方式。就目前而言,你可以通过传递rdd.partitioner 来直接使用源RDD 的分区方式。
combineByKey() 有多个参数分别对应聚合操作的各个阶段,因而非常适合用来解释聚合操作各个阶段的功划分。为了更好地演示combineByKey() 是如何工作的,下面来看看如何计算各键对应的平均值:
在Python 中使用combineByKey() 求每个键对应的平均值
sumCount = nums.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])))
sumCount.map(lambda key, xy: (key, xy[0]/xy[1])).collectAsMap()
在Scala 中使用combineByKey() 求每个键对应的平均值
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(_))
在Java 中使用combineByKey() 求每个键对应的平均值
public static class AvgCount implements Serializable {
public AvgCount(int total, int num) { total_ = total; num_ = num; }
public int total_;
public int num_;
public float avg() { returntotal_/(float)num_; }
}
Function<Integer, AvgCount> createAcc = new Function<Integer, AvgCount>() {
public AvgCount call(Integer x) {
return new AvgCount(x, 1);
}
};
Function2<AvgCount, Integer, AvgCount> addAndCount =
new Function2<AvgCount, Integer, AvgCount>() {
public AvgCount call(AvgCount a, Integer x) {
a.total_ += x;
a.num_ += 1;
return a;
}
};
Function2<AvgCount, AvgCount, AvgCount> combine =
new Function2<AvgCount, AvgCount, AvgCount>() {
public AvgCount call(AvgCount a, AvgCount b) {
a.total_ += b.total_;
a.num_ += b.num_;
return a;
}
};
AvgCount initial = new AvgCount(0,0);
JavaPairRDD<String, AvgCount> avgCounts =
nums.combineByKey(createAcc, addAndCount, combine);
Map<String, AvgCount> countMap = avgCounts.collectAsMap();
for (Entry<String, AvgCount> entry : countMap.entrySet()) {
System.out.println(entry.getKey() + ":" + entry.getValue().avg());
}
combineByKey() 数据流示意图
有很多函数可以进行基于键的数据合并。它们中的大多数都是在combineByKey() 的基础上实现的,为用户提供了更简单的接口。不管怎样,在Spark 中使用这些专用的聚合函数,始终要比手动将数据分组再归约快很多。
Spark中的CombineKey()详解的更多相关文章
- Spark中的分区方法详解
转自:https://blog.csdn.net/dmy1115143060/article/details/82620715 一.Spark数据分区方式简要 在Spark中,RDD(Resilien ...
- [Spark内核] 第36课:TaskScheduler内幕天机解密:Spark shell案例运行日志详解、TaskScheduler和SchedulerBackend、FIFO与FAIR、Task运行时本地性算法详解等
本課主題 通过 Spark-shell 窥探程序运行时的状况 TaskScheduler 与 SchedulerBackend 之间的关系 FIFO 与 FAIR 两种调度模式彻底解密 Task 数据 ...
- Spark log4j日志配置详解(转载)
一.spark job日志介绍 spark中提供了log4j的方式记录日志.可以在$SPARK_HOME/conf/下,将 log4j.properties.template 文件copy为 l ...
- php中关于引用(&)详解
php中关于引用(&)详解 php的引用(就是在变量或者函数.对象等前面加上&符号) 在PHP 中引用的意思是:不同的变量名访问同一个变量内容. 与C语言中的指针是有差别的.C语言中的 ...
- JavaScript正则表达式详解(二)JavaScript中正则表达式函数详解
二.JavaScript中正则表达式函数详解(exec, test, match, replace, search, split) 1.使用正则表达式的方法去匹配查找字符串 1.1. exec方法详解 ...
- AngularJS select中ngOptions用法详解
AngularJS select中ngOptions用法详解 一.用法 ngOption针对不同类型的数据源有不同的用法,主要体现在数组和对象上. 数组: label for value in a ...
- 【转载】C/C++中extern关键字详解
1 基本解释:extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义.此外extern也可用来进行链接指定. 也就是说extern ...
- oracle中imp命令详解 .
转自http://www.cnblogs.com/songdavid/articles/2435439.html oracle中imp命令详解 Oracle的导入实用程序(Import utility ...
- Android中Service(服务)详解
http://blog.csdn.net/ryantang03/article/details/7770939 Android中Service(服务)详解 标签: serviceandroidappl ...
随机推荐
- Python3+Appium学习笔记07-元素定位工具UI Automator Viewer
这篇主要说下如何使用UI Automator Viewer这个工具来定位元素.这个工具是sdk自带的.在sdk安装目录Tools目录下找到uiautomatorviewer.bat并启动它 如果启 ...
- 使用raw input 代替全局键盘钩子
//关于raw input 请查看msdn https://msdn.microsoft.com/en-us/library/windows/desktop/ms645536%28v=vs.85%29 ...
- JS 截取地址栏指定字符后的内容
一.获取地址栏路径 var url = window.location.href; 二.截取指定字符后的内容 /** * 截取指定字符后的内容 * @param url 路径 * @param par ...
- vue3.0脚手架 创建项目
1.下载node最新稳定版本,并且安装 2.安装好之后,在cmd或者terminal下, 使用npm -v 查看当前npm版本,验证是否安装成功 3.安装成功后,运行 npm i -g @vue/cl ...
- Pycharm----显示tab制表符
设置前: 设置后: 操作方法:
- 基于 Go 的可嵌入脚本语言 zygomys
zygomys zygomys 是一种可嵌入的脚本语言. 它是一个具有面向对象风格的现代化 Lisp,提供了一个解释器和 REPL(Read-Eval-Print-Loop:也就是说,它带有一个命令行 ...
- C# 任务、线程、同步(一)
static object taskMethodLock = new object(); static void TaskMethod(object title) { lock (taskMethod ...
- HashMap判断键是否为null
用containsKey(),而不用get(): HashMap中,null可以作为键,这样的键只有一个:可以有一个或多个键所对应的值为null.当get()方法返回null值时,即可以表示HashM ...
- ueditor批量上传word图片
图片的复制无非有两种方法,一种是图片直接上传到服务器,另外一种转换成二进制流的base64码目前限chrome浏览器使用首先以um-editor的二进制流保存为例:打开umeditor.js,找到UM ...
- SpingMVC入门
Springmvc简介及配置 1. 什么是springMVC? Spring Web MVC是一种基于Java的实现了MVC设计模式的.请求驱动类型的.轻量级Web框架. 2. SpringMVC处理 ...