aggregateByKey、aggregate理解

aggregateByKey的三个参数解释: 第一个参数:每个分区中不同key的初始值
第二个参数:分区内对相同key的值的自定义函数(需要带上第一个参数) 第三个参数:不同分区中相同key的值的自定义函数

比如:aggregateByKey(0)(math.max(,),+)

def main(args: Array[String]): Unit = {
val sparkConf = new SparkConf().setMaster("local[2]").setAppName("test")
val sc = new SparkContext(sparkConf)

val rdd: RDD[(String, Int)] = sc.makeRDD(List(("a",1),("a",2),("b",3),("c",1),("b",2),("c",4)),3)
rdd.mapPartitionsWithIndex{
(ptn:Int,iter:Iterator[(String,Int)])=>{
println(ptn+":"+iter.toList)
iter
}
}.collect()
val value: RDD[(String, Int)] = rdd.aggregateByKey(0)((x: Int, y: Int) => (
math.max(x, y)
), (x: Int, y: Int) => {
x + y
})

value.foreach(println)
sc.stop()
}

结果:

[Stage 0:> (0 + 0) / 3]
1:List((b,3), (c,1))
0:List((a,1), (a,2))
2:List((b,2), (c,4))

(a,2)
(c,5)
(b,5)

Process finished with exit code 0

分析:
1.分区内部比较,第一个值先和初始值比较,取最大值,后续依次比较
2.分区间求和,相同分区的value值求和,此时初始值不再参与该过程

分区内操作:
0 号分区 输出(a,2)
1 号分区输出(b,3) (c,1)
2 号分区输出(b,2) (c,4)

分区间操作:
相同key进行合并操作,输出
(a,2)
(b,5)
(c,5)

aggregate的三个参数解释: 第一个参数:每个分区中的初始值 第二个参数:分区内的自定义函数(需要带上第一个参数)
第三个参数:不同分区中自定义函数

def main(args: Array[String]): Unit = {
val sparkConf = new SparkConf().setMaster("local[2]").setAppName("test")
val sc = new SparkContext(sparkConf)

val rdd: RDD[Int] = sc.makeRDD(List(1,2,3,4),4)

rdd.mapPartitionsWithIndex((ptn:Int,iter:Iterator[Int])=>{
println("ptn: "+ptn+" value: "+iter.toList)
iter
}).collect()

val value: Int = rdd.aggregate(10)((x: Int, y: Int) => {
println("seqOp x:" + x + " y:" + y)
math.max(x, y)
}, (x: Int, y: Int) => {
println("combOp x:" + x + " y:" + y)
x + y
})
println("value:"+value)
sc.stop()
}

结果:

[Stage 0:> (0 + 0) / 4]
ptn: 0 value: List(1)
ptn: 1 value: List(2)
ptn: 3 value: List(4)
ptn: 2 value: List(3)
seqOp x:10 y:2
seqOp x:10 y:1
combOp x:10 y:10
combOp x:20 y:10
seqOp x:10 y:3
seqOp x:10 y:4
combOp x:30 y:10
combOp x:40 y:10
value:50

Process finished with exit code 0

分析:
1.分区内部比较,第一个值先和初始值比较,取最大值,后续依次比较
2.分区间求和,相同分区的value值求和,此时初始值参与该求和过程

分区内操作
由于数据均分分布在4个分区,每个分区内数据,均与初始值 10 进行比较,获取最大值均为10

分区间操作
分区间求和,值为 40,初始值参与该过程,40+10=50

将seqOp修改为 求和,分区依旧为 3,结果为:
分区内操作,每个分区内 第一个数值与初始值相加,后续依次累加,例如:
seqOp x:10 y:3
seqOp x:13 y:4
分区间操作,分区间,第一个数值与初始值相加,后续依次累加,例如:
combOp x:10 y:11
combOp x:21 y:12
combOp x:33 y:17

实际输出如下:

ptn: 0 value: List(1)
ptn: 1 value: List(2)
ptn: 2 value: List(3, 4)
seqOp x:10 y:2
seqOp x:10 y:1
seqOp x:10 y:3
seqOp x:13 y:4
combOp x:10 y:11
combOp x:21 y:12
combOp x:33 y:17
value:50

Process finished with exit code 0

将seqOp修改为 求和,分区依旧为 4,结果为:

[Stage 0:> (0 + 2) / 4]
ptn: 1 value: List(2)
ptn: 0 value: List(1)
ptn: 3 value: List(4)
ptn: 2 value: List(3)
seqOp x:10 y:1
seqOp x:10 y:2
seqOp x:10 y:3
seqOp x:10 y:4
combOp x:10 y:11
combOp x:21 y:13
combOp x:34 y:12
combOp x:46 y:14
value:60

Process finished with exit code 0

将seqOp修改为 求和,分区依旧为 5,结果为:

ptn: 0 value: List()
ptn: 1 value: List(1)
ptn: 2 value: List(2)
ptn: 3 value: List(3)
ptn: 4 value: List(4)
seqOp x:10 y:1
combOp x:10 y:11
seqOp x:10 y:2
combOp x:21 y:10
seqOp x:10 y:3
combOp x:31 y:12
seqOp x:10 y:4
combOp x:43 y:13
combOp x:56 y:14
value:70

Process finished with exit code 0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值