3.2 Spark RDD 基本转换操作5-mapPartitions、mapPartitionsWithIndex

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yyl424525/article/details/78370777

1 mapPartitions
def mapPartitions[U](f: (Iterator[T]) => Iterator[U], preservesPartitioning: Boolean = false)(implicit arg0: ClassTag[U]): RDD[U]
该函数和map函数类似,只不过映射函数的参数由RDD中的每一个元素变成了RDD中每一个分区的迭代器。如果在映射的过程中需要频繁创建额外的对象,使用mapPartitions要比map高效的过。
比如,将RDD中的所有数据通过JDBC连接写入数据库,如果使用map函数,可能要为每一个元素都创建一个connection,这样开销很大,如果使用mapPartitions,那么只需要针对每一个分区建立一个connection。
参数preservesPartitioning表示是否保留父RDD的partitioner分区信息。
例子:

var rdd1 = sc.makeRDD(1 to 5,2)
//rdd1有两个分区
scala> :paste
// Entering paste mode (ctrl-D to finish)

var rdd3=rdd1.mapPartitions{iter=>{
var result=List[Int]()
var sum=0
while(iter.hasNext){
sum+=iter.next()
}
result.::(sum).iterator
}
}
// Exiting paste mode, now interpreting.
rdd3: org.apache.spark.rdd.RDD[Int] = MapPartitionsRDD[17] at mapPartitions at <console>:23
:paste进入多行输入
ctrl+d退出多行输入并运行

//rdd3将rdd1中每个分区中的数值累加,第一个分区是(1,2),第二个分区是(3,4,5)
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,不过提供了两个参数,第一个参数为分区的索引。
例子:

//rdd1有两个分区
var rdd1 = sc.makeRDD(1 to 5,2)

//rdd2将rdd1中每个分区的数字累加,并在每个分区的累加结果前面加了分区索引
scala> :paste
// Entering paste mode (ctrl-D to finish)
var rdd2 = rdd1.mapPartitionsWithIndex{
        (index,iter) => {
          var result = List[String]()
            var sum= 0
            while(iter.hasNext){
              sum += iter.next()
            }
            result.::(index + "|" + sum).iterator

        }
      }

scala> rdd2.collect
res13: Array[String] = Array(0|3, 1|12)

猜你喜欢

转载自blog.csdn.net/yyl424525/article/details/78370777
今日推荐