原文请参考:https://blog.csdn.net/youbitch1/java/article/details/88581251

 

aggregate:    https://blog.csdn.net/bitcarmanlee/article/details/78088304

原理:   源码 :  def aggregate[U: ClassTag](zeroValue: U)(seqOp: (U, T) => U, combOp: (U, U) => U): U

aggregate先对每个分区的元素做聚集,然后对所有分区的结果做聚集,聚集过程中,使用的是给定的聚集函数以及初始值”zero value”。这个函数能返回一个与原始RDD不同的类型U,因此,需要一个合并RDD类型T到结果类型U的函数,还需要一个合并类型U的函数。这两个函数都可以修改和返回他们的第一个参数,而不是重新新建一个U类型的参数以避免重新分配内存。
参数zeroValue:seqOp运算符的每个分区的累积结果的初始值以及combOp运算符的不同分区的组合结果的初始值 - 这通常将是初始元素(例如“Nil”表的列表 连接或“0”表示求和)
参数seqOp: 每个分区累积结果的聚集函数。
参数combOp: 一个关联运算符用于组合不同分区的结果

例子

val list = List(1,2,3,4,5,6,7,8,9)
val (mul, sum, count) = sc.parallelize(list, 2).aggregate((1, 0, 0))     //(mul, sum, count) --->(1, 0, 0)  初始值
( (acc, number)
=> (acc._1 * number, acc._2 + number, acc._3 + 1), //单一区的元素做聚集 (x, y) => (x._1 * y._1, x._2 + y._2, x._3 + y._3) //聚合多区 x or y 对应 (mul, sum, count)
) (sum
/ count, mul) 原文链接:https://blog.csdn.net/bitcarmanlee/java/article/details/78088304

在常见的求均值的基础上稍作了变动,sum是求和,count是累积元素的个数,mul是求各元素的乘积。
解释一下具体过程:
1.初始值是(1, 0 ,0)
2.number是函数中的T,也就是List中的元素,此时类型为Int。而acc的类型为(Int, Int, Int)。acc._1 * num是各元素相乘(初始值为1),acc._2 + number为各元素相加。
3.sum / count为计算平均数。

 

 

数据混洗:

    因为常常有重复的元素.如果只要唯一的元素,我们可以使用RDD.distinct() 转化操作来生成一个只包含不同元素的新RDD
    不过distinct操作的开销很大,因为数据是通过网络混洗的,后续再继续了解下有没有优化的办法

集合操作:

    union
        返回一个包含两个 RDD 中所有元素的 RDD
        如果输入的RDD中有重复数据,Spark的union()操作也会去除重复数据
    intersection
        只返回两个RDD中都有的元素
        intersection() 在运行时也会去掉所有重复的元素()单个RDD内的重复元素也会一起移除)
        intersection性能比union差,它需要通过网络混洗数据来发现共有的元素

原文链接:https://blog.csdn.net/youbitch1/java/article/details/88581251

 

posted on 2020-07-02 18:29  lshan  阅读(137)  评论(0编辑  收藏  举报