import org.apache.spark.{SparkConf, SparkContext} import org.apache.spark.rdd.RDD /** * Created by EA on 2016/8/24. */ object Test3 { def main(args: Array[ String ]) { val conf = new SparkConf().setAppName("ScalaTest").setMaster("local") val sc = new SparkContext(conf) val rddInt: RDD[ Int ] = sc.parallelize(List(1, 2, 3, 4, 5), 3) //定义一个Int类型的List,初始值为:1~5,分布在3个分区上 val rddAggr1: (Int, Int) = rddInt.aggregate((0, 0))((x, y) => (x._1 + y, x._2 + 1), (x, y) => (x._1 + y._1, x._2 + y._2)) //( ⊙o⊙ )?)一看懵了,我们分开来,一个一个看,就比较好理解了: //aggregate 返回一个2元组,元组内第一个值为List中所有数据求和,第二个值为List中的数据个数 //aggregate 其中(0,0) Int二元组,是参与计算的初始值 // 第一个0是参与求和的初始值,第二个0是参与求个数的初始值 //((x, y) => (x._1 + y, x._2 + 1), (x, y) => (x._1 + y._1, x._2 + y._2))分成两部分看: //(x, y) => (x._1 + y, x._2 + 1) 单线程求和过程; //(x, y) => (x._1 + y._1, x._2 + y._2) 各分区求和过程; // (x, y) => (x._1 + y, x._2 + 1)理解如下: //x._1为元组的第一个值,y为List中的各个值 //x._2为元组的第二个值,1为每次加1 //计算过程: //x._1 + y 取元组(0,0)中 的第一个值0作为加数,与List中的第一个值1作为被加数相加,得到结果1; //x._2 + 1 取元组(0,0)中的第二个值0作为加数,1作为被加数,得到结果1; //以上两结果构成新元组(1,1),再以元组(1,1)与List中第二个值2求和(1+2=3,1+1=2) //得到又一个新元组(3,2),以此类推,计算完所有数据求和,得到最终元组(15,5) //(x, y) => (x._1 + y._1, x._2 + y._2)理解如下: //以上求和过程为单线程计算过程,实际spark执行是分布式的 // 即,可能会把Lit(1,2,3,4,5)分为多个区,如:P1(1,2),P2(3,4),P3(5) //各区计算结果:(3,2),(7,2),(5,1) //每个区以单线程方式计算结果,最后再将各个区的计算结果合并 //(x, y) => (x._1 + y._1, x._2 + y._2)为每个区的计算结果元组相加 // 即,(3+7+5,2+2+1)得到(15,5)作为最终返回的二元组 //这里的x,y与前面的x,y没有关系 //此处的x._1可以理解为第一个分区的计算结果二元组的第一个值,x._2第二个值 //y._1与y._2可以理解为第二个分区的计算结果二元组的两个值 // 两个分区的计算结果合并后,作为新的元组,再与第三个分区合并,得到最终结果 println("rddAggr1:" + rddAggr1) // (15,5) //理解了上面的过程,改成下面的计算就更清楚了(列表中数据乘积,并求个数) val rddAggr2: (Int, Int) = rddInt.aggregate((1, 0))((x, y) => (x._1 * y, x._2 + 1), (x, y) => (x._1 * y._1, x._2 + y._2)) println("rddAggr2:" + rddAggr2) // (120,5) } }
Spark RDD中的aggregate函数理解
猜你喜欢
转载自lguan.iteye.com/blog/2319917
今日推荐
周排行