键值对转换算子--最重要的算子combineByKey

  • 定义:combineByKey(createCombiner,mergePart,mergerbine )
combineByKey需要传递三个参数(函数)
1、createCombiner函数 将相同key值的某一个value数据进行一个函数操作,得到一个新的value数据---零值(新的value数据是我们后期聚合的数据)
v=>U
2、mergepart函数 将同一个分区中key值相同的value数据(上一步函数中转换得到的新的value) 聚合操作
(U,V)=>U
3、mergercombin函数 将不同分区中key值相同的聚合出来的结果再进行一次聚合操作
(U,U)=>U
  • 解释:
解释 区别
reduce 对所有的数据进行聚合 数据类型无法定义
aggregateByKey 可以实现每个分区先聚合,然后再整体聚合 效率高,但是每一个分区聚合或者不同分区聚合的时候都必须和零值进行聚合
combineBykey 可以实现每个分区先聚合,然后再整体聚合 效率高,且不需要传递零值,到底对什么样的数据进行聚合,自定义
  • 案例:
object CombineByKeyTransRDD {
def main(args: Array[String]): Unit = {
val sparkConf = new SparkConf().setMaster("local").setAppName("kv")
val sc = new SparkContext(sparkConf)
combineByKeyOpt(sc)
sc.stop()
}
def combineByKeyOpt(sc: SparkContext): Unit = {
println("----------------combineByKey开始------------------")
val rdd: RDD[(String,Int)] = sc.makeRDD(Array(("zs",60),("zs",70),("zs",80),("ls",66),("ls",60),("ls",77)))
// 案例一:计算每一个学生的总分
val sum: RDD[(String, Int)] = rdd.combineByKey(
(a: Int) => {
a
},
(a: Int, b: Int) => {
a + b
},
(a: Int, b: Int) => {
a + b
}
)
/*
(ls,203)
(zs,210)
*/
sum.foreach(println(_))
// 案例二:计算平均分
val value = rdd.combineByKey(
// (60, 1)
(a: Int) => {
(a, 1)
},
// 70 (60, 1) => (130, 2) 80 => (210, 3)
(tuple2: (Int, Int), score: Int) => {
(tuple2._1 + score, tuple2._2 + 1)
},
(tuplea: (Int, Int), tupleb: (Int, Int)) => {
(tuplea._1 + tupleb._1, tuplea._2 + tupleb._2)
}
)
value.foreach(println(_)) // (ls,(203,3)) (zs,(210,3))
val rdd4 = value.mapValues(tuple2 => {
tuple2._1 / tuple2._2.toDouble
})
rdd4.foreach(println(_)) // (ls,67.66666666666667) (zs,70.0)
println("----------------combineByKey结束------------------")
}
}
posted @   jsqup  阅读(36)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示