1、aggregate
首先看下 aggregate 函数签名
def aggregate[U: ClassTag](zeroValue: U)(seqOp: (U, T) => U, combOp: (U, U) => U): U
说明
参数zeroValue:seqOp运算符的每个分区的累积结果的初始值以及combOp运算符的不同分区的组合结果的初始值 - 这通常将是初始元素(例如“Nil”表的列表 连接或“0”表示求和) 参数seqOp: 每个分区累积结果的聚集函数。 参数combOp: 一个关联运算符用于组合不同分区的结
应用举例
数据准备
//获取 SparkConf 并设置应用名称*本地模式 val conf: SparkConf = new SparkConf().setAppName("Spark").setMaster("local[*]") //获取 Spark 上下文对象 val sc: SparkContext = new SparkContext(conf) val rdd:RDD[Int] = sc.makeRDD(List(1, 2, 3, 4), 2) rdd.mapPartitionsWithIndex { case (index, data) => { println(index + " -> " + data.mkString(",")) } data }.collect().foreach(println)
输出
1 -> 3,4 0 -> 1,2
需求1:默认值 0 ,分区内求和,分区间求和
println(rdd.aggregate(0)(_ + _, _ + _))
分析
/** * 0 -> 0 + 1 + 2 => 3 * 1 -> 0 + 3 + 4 => 7 * 0 -> 3 * 1 -> 7 * 0 + 3 + 7 * 10 + 0 * 10 */
需求2:默认值 10 ,分区内求和,分区间求和
/** * 0 -> 10 + 1 + 2 => 13 * 1 -> 10 + 3 + 4 => 17 * 0 -> 13 * 1 -> 17 * 10 + 13 + 17 * 40 */
需求3:分区内求最大值,分区间求和
println(rdd.aggregate(2)(math.max(_, _), _ + _))
分析
/** * 0 -> max(2,1,2) => 2 * 1 -> max(2,3,4) => 4 * 0 -> 2 * 1 -> 4 * 2 + 2 + 4 * 8 */
接下来看下 书本上的一个案例
val tuple: (Int, Int) = rdd.aggregate((0, 0))( (acc, value) => (acc._1 + value, acc._2 + 1), (acc1, acc2) => (acc1._1 + acc2._1, acc1._2 + acc2._2) ) println(tuple) println(tuple._1 / tuple._2.toDouble)