Spark聚合操作combineByKey()

park中對鍵值對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  分區函數()

準備數據:

1

2

3

4

5

6

7

8

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.遍歷過程中,統計課程的數目,同時計算總分。

1

2

3

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. 獲得最終結果

 

統計得到的結果:得到姓名:科目+總分

1

2

3

scala> score2.foreach(println)

(tom,(3,275.0))

(jack,(3,263.0))

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章