Spark算子:transformation之mapPartitions、mapPartitionsWithIndex

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)

 

你可能感兴趣的:(spark,scala)