spark入门四(RDD高级算子一)

1. mapPartitionsWithIndex

创建RDD,指定分区数为2

scala> val rdd1 = sc.parallelize(List(1,2,3,4,5,6,7),2)

查看分区

scala> rdd1.partitions

– 内容如下:

res0: Array[org.apache.spark.Partition] = Array(org.apache.spark.rdd.ParallelCollectionPartition@691, org.apache.spark.rdd.ParallelCollectionPartition@692)

查看分区数量

scala> rdd1.partitions.length   //结果: res1: Int = 2

创建一个迭代函数

def func(index : Int, iter : Iterator[Int]) : Iterator[String] = {
	iter.toList.map(x => "[partID:" + index + ",val: " + x +"]").iterator
}

查看分区内容

scala> rdd1.mapPartitionsWithIndex(func).collect()

内容如下:

res2: 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], [partID:1,val: 7])

2. aggregate 聚合 更灵活

创建RDD

scala>  val rdd = sc.parallelize(List(1,2,3,4,5,6,7,8,9),2)	

RDD求和

scala>   rdd.aggregate(0)(_+_,_+_)

求每个分区最大值的工作,再对最大值求和

引导: 如何求数组最大值:val arr = Array(1,2,3)
arr.reduce(math.max(,)) //获取到最大值为3

scala> rdd.aggregate(0)(math.max(_,_),_+_)  

结果为:res6: Int = 13
说明:第一个分区最大值为4,第二个为9,加起来为13

求最大值:

scala> rdd.aggregate(0)(math.max(_,_),math.max(_,_))
res0: Int = 9 

这里面有个问题:初始值为0,必须小于数组里面所有的元素才可以,否则结果报错。为了避免这个问题,可以将初始值定义为rdd的第一个元素,代码如下:

scala> rdd.aggregate(rdd.first)(math.max(_,_),math.max(_,_))
res6: Int = 9

练习:

scala> rdd.aggregate(10)(math.max(_,_),_+_)
res7: Int = 30

说明:
初始值为10
10 和 第一个分区最大值4比较,结果为10
10 和 第一个分区最大值9比较,结果为10
结果为:10+10+10 = 3

scala> rdd.aggregate(6)(math.max(_,_),_+_)
res8: Int = 21

说明:
初始值为6
6 和 第一个分区最大值4比较,结果为6
6 和 第一个分区最大值9比较,结果为9
结果为:6+6+9 = 21

scala> rdd.aggregate(3)(math.max(_,_),_+_)
res9: Int = 16

说明:
初始值为3
3 和 第一个分区最大值4比较,结果为4
3 和 第一个分区最大值9比较,结果为9
结果为:3+4+9 = 16

scala> val rdd1 = sc.parallelize(List("a","b","c","d","e"),2)
rdd1: org.apache.spark.rdd.RDD[String] = ParallelCollectionRDD[3] at parallelize at <console>:24
scala> rdd1.aggregate("")(_+_,_+_)
res10: String = abcde
def func2(index : Int, iter : Iterator[String]) : Iterator[String] = {
	iter.toList.map(x => "[partID:" + index + ",val: " + x +"]").iterator
}
```java

```java
scala> rdd1.mapPartitionsWithIndex(func2).collect()
res13: Array[String] = Array([partID:0,val: a], [partID:0,val: b], [partID:1,val: c],[partID:1,val: d], [partID:1,val: e])
scala> rdd1.aggregate("|")(_+_,_+_)
res15: String = ||ab|cde
scala> val rdd2 = sc.parallelize(List("12","23","345","4567"),2)
rdd2: org.apache.spark.rdd.RDD[String] = ParallelCollectionRDD[6] at parallelize at <console>:24

scala> rdd2.aggregate("")((x,y)=>math.max(x.length,y.length).toString,(x,y)=>x+y);
res16: String = 24

scala> rdd2.aggregate("")((x,y)=>math.max(x.length,y.length).toString,(x,y)=>x+y);
res17: String = 42

scala> rdd2.aggregate("")((x,y)=>math.max(x.length,y.length).toString,(x,y)=>x+y);
res18: String = 24

scala> rdd2.aggregate("")((x,y)=>math.max(x.length,y.length).toString,(x,y)=>x+y);
res19: String = 42

说明:
相同的代码,得到的结果有两个,
第一个分区最大长度是2,第二个分区最大长度是4,
因为有两个分区计算,并不知道哪个先返回,所以会有两个结果。

scala> val rdd3 = sc.parallelize(List("12","23","345",""),2)	

scala> rdd3.aggregate("")((x,y)=>math.min(x.length,y.length).toString,(x,y)=>x+y);
res25: String = 01

scala> rdd3.aggregate("")((x,y)=>math.min(x.length,y.length).toString,(x,y)=>x+y);
res26: String = 10

scala> rdd3.aggregate("")((x,y)=>math.min(x.length,y.length).toString,(x,y)=>x+y);
res27: String = 10

scala> rdd3.aggregate("")((x,y)=>math.min(x.length,y.length).toString,(x,y)=>x+y);
res28: String = 01

说明:
第一个分区:
初始值""长度0和"12"的长度2比较,结果为0,调用toString,结果为 “0”
再将 "0"长度为1和 “23"的长度2比较,结果为1,调用toString,结果为 “1”
第二个分区:
初始值”"长度0和"345"的长度3比较,结果为0,调用toString,结果为 “0”
再将 "0"长度为1和 ""的长度0比较,结果为0,调用toString,结果为 “1”
因为有两个分区计算,并不知道哪个先返回,所以会有两个结果。

3. aggregateByKey 把相同的Key进行操作

//1. 创建k-v对RDD
scala> val pairRDD = sc.parallelize(List(("cat",2),("cat",5),("mouse",4),("cat",12),("cat",13),("mouse",2)))
pairRDD: org.apache.spark.rdd.RDD[(String, Int)] = ParallelCollectionRDD[9] at parallelize at <console>:24
//2. 查看内容
def func3(index : Int, it : Iterator[Any]) : Iterator[Any] = {
    it.toList.map(x => "[partID:" + index + ",val: " + x +"]").iterator
}

scala> pairRDD.mapPartitionsWithIndex(func3).collect()
res30: Array[Any] = Array([partID:0,val: (cat,2)], [partID:0,val: (cat,5)], [partID:0,val: (mouse,4)], [partID:1,val: (cat,12)], [partID:1,val: (cat,13)], [partID:1,val: (mouse,2)])
//统计每种动物的总数量,分区求和,再求和
scala> pairRDD.aggregateByKey(0)(_+_,_+_).collect()
res31: Array[(String, Int)] = Array((cat,32), (mouse,6))

//将每种动物的每个分区最大数量的那个元素求出来,再对每个分区求和
scala> pairRDD.aggregateByKey(0)(math.max(_,_),_+_).collect()
res32: Array[(String, Int)] = Array((cat,18), (mouse,6))

//将每种动物的最大数量的那个元素求出来
scala> pairRDD.aggregateByKey(0)(math.max(_,_),math.max(_,_)).collect()
res33: Array[(String, Int)] = Array((cat,13), (mouse,4))

完…

猜你喜欢

转载自blog.csdn.net/guo20082200/article/details/83143868