1、mapPartitions:
def mapPartitions[U](f: (Iterator[T]) => Iterator[U], preservesPartitioning: Boolean = false)(implicit arg0: ClassTag[U]): RDD[U]
该函数类似于map,只不过映射函数的参数是RDD每个分区的迭代器。若在映射的过程中需要频繁地创建额外的对象,使用mapPartitions要比map高效。preservesPartitioning参数表示是否保留父RDD的分区信息。
var rdd1 = sc.makeRDD(1 to 5,2)
//rdd1有两个分区,分别计算两个分区的元素和存到result
scala> var rdd3 = rdd1.mapPartitions{ x => {
var result = List[Int]()
var i = 0
while(x.hasNext){
i += x.next()
}
result.::(i).iterator
}}
rdd3: org.apache.spark.rdd.RDD[Int] = MapPartitionsRDD[84] at mapPartitions at :23
//rdd3将rdd1中每个分区中的数值累加
scala> rdd3.collect
res65: Array[Int] = Array(3, 12)
scala> rdd3.partitions.size
res66: Int = 2
2、mapPartitionsWithIndex:
def mapPartitionsWithIndex[U](f:(Int, Iterator[T]) => Iterator[U], preservesPartitioning: Boolean = false)(implicit arg0: ClassTag[U]): RDD[U]
该函数与mapPartitions的作用相同,只是多一个分区索引参数。
var rdd1 = sc.makeRDD(1 to 5,2)
//rdd1有两个分区
var rdd2 = rdd1.mapPartitionsWithIndex{
(x,iter) => {
var result = List[String]()
var i = 0
while(iter.hasNext){
i += iter.next()
}
result.::(x + "|" + i).iterator
}
}
//rdd2将rdd1中每个分区的数字累加,并在每个分区的累加结果前面加了分区索引
scala> rdd2.collect
res13: Array[String] = Array(0|3, 1|12)