combineByKey:第一个传入的参数不再是初始值,意味着可以对数据的类型发生变化
def combineByKey[C](createCombiner: V => C,mergeValue: (C, V) => C,mergeCombiners: (C, C) => C): RDD[(K, C)]
createCombiner
: 分区内,相同的key的value只执行一次,后续的value,执行mergeValue函数
mergeValue
:分区内操作函数,相同key的剩余的value,和createCombiner得到的结果进行mergeValue操作
mergeCombiners
: 分区间操作函数,相同的key进行mergeCombiners操作
RDD[(K, C)]
:返回值类型,最后是元组啦,所以有多少个不同的key就有多少个元组
示例:根据key,求每种key的均值
思路:
上代码:
val z=sc.makeRDD(List(("a",1),("b",2),("a",2),("a",3),("b",0)),2)
z.glom.collect // Array(Array((a,1), (b,2)), Array((a,2), (a,3), (b,0)))
var w=z.combineByKey(x=>(x,1),(x:(Int,Int),y:Int)=>(x._1+y,x._2+1),(x:(Int,Int),y:(Int,Int))=>(x._1+y._1,x._2+y._2))
w.collect //Array[(String, (Int, Int))] = Array((b,(2,2)), (a,(6,3)))
var v=w.map(x=>(x._1,x._2._1/(x._2._2).toDouble)) //求均值
v.collect //Array[(String, Double)] = Array((b,1.0), (a,2.0))
combineByKey代码解析:
var z1=z.map(x=>(x._1,(x._2,1))).reduceByKey((x,y)=>(x._1+y._1,x._2+y._2))
z1.collect //Array((b,(2,2)), (a,(6,3)))
var z2=z1.map(x=>(x._1,x._2._1/(x._2._2).toDouble)) //求均值
z2.collect // Array((b,1.0), (a,2.0))
其实思路都差不多啦,都要将原始数据转成(key,(sum,num))格式