Spark聚合操作:combineByKey()

摘要:
在Spark中,基于RDD键的聚合函数的键值通过combineByKey()实现。它允许用户返回不同于输入数据类型的返回值。首先,了解combineByKey是一个聚合函数。例如,对于实际使用场景,计算两名学生在三门科目中的平均分数。其参数形式为:combineByKey。例如,我有一个数组{1,2,1,2,4}。具体过程是:当第一次遇到1时,调用createCombiner()函数。接下来,解释每个功能1的功能。createCombiner():在遍历过程中,当遇到新的键时,将调用createCombiner()函数。

Spark中对键值对RDD(pairRDD)基于键的聚合函数中,都是通过combineByKey()实现的。

它可以让用户返回与输入数据类型不同的返回值(可以自己配置返回的参数,返回的类型)

首先理解:combineByKey是一个聚合函数,实际使用场景比如,对2个同学的3门考试科目成绩,分别求出他们的平均值。

(也就是对3门考试成绩进行聚合,用一个平均数来表示)

combineByKey是通过3个内部函数来解决这个问题的:

具体处理过程为:遍历分区中的所有元素,因此每一个元素的键要么没有遇到过,要么就和之前的键相等。

它的参数形式为:combineByKey(1.createCombiner,2.mergeValue,3.mergeCombiners,4.partioner)

比如,我有一个数组{1,2,1,2,4}  

具体流程为:第一次遇到1,调用createCombiner()函数。

2.第一次遇到2,调用createCombiner()函数。

3.第二次遇到1,调用mergeValue()函数。

4.第二次遇到2,调用mergeValue()函数。

5.第一次遇到4,调用mergeValue()函数。

接下来解释每一个函数的作用

1.createCombiner():在遍历过程中,遇到新的键,就会调用createCombiner()函数。这个过程会发生在每一个分区内,因为RDD中有不同的分区,也就有同一个键调用多次createCombiner的情况。

2.mergeValue() 遇到已经重复的键,调用mergeValue()函数。

3.mergeCombiners() 如果有2个或者更多的分区,会把分区的结果合并。

4.pationer  分区函数()

举例:

准备数据:

val scores =sc.parallelize(Array(
("jack",89.0),
("jack",82.0),
("jack",92.0),
("tom",88.0),
("tom",89.0),
("tom",98.0)
))

  数据为jack和tom的3门科目成绩,要对jack和tom的平均成绩进行输出。

1.遍历过程中,统计课程的数目,同时计算总分。

val score2=scores.combineByKey(x =>(1,x) ,
(c1:(Int,Double),newScore)=>(c1._1+1,c1._2+newScore),
(c1:(Int,Double),c2:(Int,Double))=>(c1._1+c2._1,c1._2+c2._2))

详解:

x =>(1,x)   将scores的value转化为(1,value)的格式
(c1:(Int,Double),newScore)=>(c1._1+1,c1._2+newScore)  遇到重复的key:我们对value的处理过程为:
之前计算的结果定义为newScore,对c1:(c1._1,c2._2)处理过程为:(c1._1+1,c2._2+newScore)  
实际意义为:再次遍历到jack时,我们将科目数量+1,将统计的总分再加上遍历到的分数。
(c1:(Int,Double),c2:(Int,Double))=>(c1._1+c2._1,c1._2+c2._2)) 对2个不同的分区c1,c2(这2个分区,他的键相同,都是Jack)
最后我们将不同分区的结果相加。
比如我们还有另一个分区("jack",45) 代表c2。我们要将Jack的科目数+1,总分+45. 获得最终结果

统计得到的结果:得到姓名:科目+总分

scala> score2.foreach(println)
(tom,(3,275.0))
(jack,(3,263.0))

  

2.求平均值:

val average=score2.map{case(name, (num,score) )=>(name,score/num) }
结果: average.foreach(println)
(tom,91.66666666666667)
(jack,87.66666666666667)

免责声明:文章转载自《Spark聚合操作:combineByKey()》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇解决'androidx.arch.core:core-runtime' has different version for the compile (2.0.0) and runtime (2.0.1)Spring5源码分析(020)——IoC篇之解析自定义标签下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

java学习--基础知识进阶第六天--集合&迭代器、增强for & 泛型、常见数据结构、List子体系

今日内容介绍 u  集合&迭代器 u  增强for & 泛型 u  常见数据结构 u  List子体系 第1章 集合&迭代器 1.1 集合体系结构 1.1.1 集合体系图      在最顶层的父接口Collection中一定定义了所有子类集合的共同属性和方法,因此我们首先需要学习Collection中共性方法,然后再去针对每个子类集...

React之JSX循环遍历方法对比

JSX支持遍历语法,如下 除了上面数组遍历方式,还有另一种,如下所示 结合for循环(外部) 注意: 主流循环写法是 map,jsx里面不能用for循环,因为for循环不是表达式。可以用Array::map方法,注意给返回的每一个组件设置一个唯一的key。 ....

算法笔试:返回第一个不重复的字符变种,不区分大小写

题目 给定一个字符串,返回字符串中第一个不重复的字符,比如aBAd返回B,AbabcfA返回c,判断时不区分给定字符大小写,但返回时需要返回原本大小写(其实就是通过索引返回即可)。 思路 1、暴力破解 使用双重循环,声明一个变量保存字符出现的次数, 第二层循环中与第一层当前循环字符比较,如果相同字符出现次数++, 如果第二层循环遍历完以后字符出现次数为1,...

游标(cursor)--显式游标&隐式游标、游标四个属性、循环遍历

https://blog.csdn.net/qq_36743482/article/details/79354036 1.1 cursor是什么cursor是光标,游标的意思。比如我们的鼠标的光标就是cursor。那么在数据库中cursor是什么呢?当运行DML(select,update,insert,delete)语句时,ORACLE会在内存中为其分配...

原生redis命令

一、 redis-cli 连接 redis 进入redis安装目录 cd /usr/local/bin 进入redis客户端 ./redis-cli -p 6379 -h 用于指定 ip -p 用于指定端口 -a 用于指定认证密码 退出客户端 quit 指定 database,默认16个数据库 select 3   二、 redis-cli 操作 redi...

jQuery遍历,数组,集合

使用了jquery有段时间了,整理下jquery中的遍历问题。 1.jquery 遍历对象 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">< HTML>  <HEAD>   <TITLE> New Document </TIT...