RDD-aggregate

Posted lucas-zhao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RDD-aggregate相关的知识,希望对你有一定的参考价值。

1. 参数:(zeroValue: U)(seqOp: (U, T) ⇒ U, combOp: (U, U) ⇒ U)

2. 作用:aggregate函数将每个分区里面的元素通过seqOp和初始值进行聚合,然后用combine函数将每个分区的结果和初始值(zeroValue)进行combine操作。这个函数最终返回的类型不需要和RDD中元素类型一致。

 

// 并行化创建RDD,有2个分区
val z = sc.parallelize(List(1,2,3,4,5,6), 2)

// 先用mapPartitionsWithIndex分区标签打印出RDD的内容
def myfunc(index: Int, iter: Iterator[(Int)]) : Iterator[String] = {
  iter.map(x => "[partID:" +  index + ", val: " + x + "]")
}

z.mapPartitionsWithIndex(myfunc).collect
// res28: Array[String] = Array([partID:0, val: 1], [partID:0, val: 2], [partID:0, val: 3], [partID:1, val: 4], [partID:1, val: 5], [partID:1, val: 6])

// 或者简写如下:
z.mapPartitionsWithIndex((idx,iter)=>(iter.map((idx,_)))).collect
// Array[(Int, Int)] = Array((0,1), (0,2), (0,3), (1,4), (1,5), (1,6))

// 应用aggreate RDD算子
// 先计算每个partition的数与初始值的最大值,得到每个分区的最大值3、6,和初始值0累加求和
z.aggregate(0)(math.max(_, _), _ + _)
// res40: Int = 9

//这个例子返回16,因为初始值是5
//分区0的最大值(5,1,2,3)= 5
//分区1的最大值为(5,4,5,6)= 6
//分区之间的最终缩减值将是5 + 5 + 6 = 16
//注:最终的值包括初始值
z.aggregate(5)(math.max(_, _), _ + _)
res29: Int = 16

// aggregate字符串拼接
val z = sc.parallelize(List("a","b","c","d","e","f"),2)
//先用分区标签打印出RDD的内容
def myfunc(index: Int, iter: Iterator[(String)]) : Iterator[String] = {
  iter.map(x => "[partID:" +  index + ", val: " + x + "]")
}

z.mapPartitionsWithIndex(myfunc).collect
res31: Array[String] = Array([partID:0, val: a], [partID:0, val: b], [partID:0, val: c], [partID:1, val: d], [partID:1, val: e], [partID:1, val: f])

// 或简写为:
z.mapPartitionsWithIndex((idx,iter)=>(iter.map((idx,_)))).collect
// Array[(Int, String)] = Array((0,a), (0,b), (0,c), (1,d), (1,e), (1,f))

scala> z.aggregate("")(_+_,_+_)
res10: String = defabc

scala> z.aggregate("")(_+_,_+_)
res13: String = abcdef
// 由于每个分区是并行计算的,因此不确定哪个分区先执行完成,
// 所以最后分区之间combine的操作无法确定哪个分区在前在后,但是初始值肯定在最前面

// 初始值不为空的情况
scala> z.aggregate("@")(_+_,_+_)
// res14: String = @@abc@def

scala> z.aggregate("@")(_+_,_+_)
// res15: String = @@def@abc

scala> z.aggregate("@")(_+_,_+_)
// res16: String = @@def@abc


// 下面是一些更高级的示例

// 求每个分区字符串长度的最大值然后拼接结果
val z = sc.parallelize(List("12","23","345","4567"),2)
z.aggregate("")((x,y) => math.max(x.length, y.length).toString, (x,y) => x + y)
// 分区0的数据为"12","23",和初始值""比较字符串的最大长度2,并转换为String "2"。
// 分区1的数据为"345","4567",和初始值""比较字符串的最大长度4,并转换为String "4"。
// 最后分区的结果和初始值拼接,得到42或者24
// res141: String = 42

// 求每个分区字符串长度的最小值然后拼接结果
z.aggregate("")((x,y) => math.min(x.length, y.length).toString, (x,y) => x + y)
// res142: String = 11

// 开始误以为结果是20或者02,其实不然,对""取length是0,0 toString之后是字符"0",
// 字符"0"的长度是1
"".length   // res24: Int = 0
"".length.toString  // res25: String = 0
 "".length.toString.length  //res26: Int = 1

以上是关于RDD-aggregate的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段——CSS选择器

谷歌浏览器调试jsp 引入代码片段,如何调试代码片段中的js

片段和活动之间的核心区别是啥?哪些代码可以写成片段?

VSCode自定义代码片段——.vue文件的模板

VSCode自定义代码片段6——CSS选择器

VSCode自定义代码片段——声明函数