spark中RDD計算是以分區爲單位的,而且計算函數都是在對迭代器複合,不需要保存每次計算的結果。mapPartitions的輸入函數是應用於每個分區,也就是把每個分區的內容作爲整體來處理的:
def mapPartitions[U:ClassTag](f:Iterator[T]=>Iterator[U], preservesPartitioning:Boolean=false):RDD[U]
f即輸入函數,它處理每個分區裏面的內容。每個分區的內容將以Iterator[T]傳遞給輸入函數f,f的輸出結果是Iterator[U]。最終的RDD由所有分區經過輸入函數處理後的結果合併起來的。在下面的例子中,函數iterfunc是把分區中的一個元素和它的下一個元素組成一個Tuple。
scala> val a=sc.parallelize(1 to 9,3)
a: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[0] at parallelize at <console>:24
scala> def iterfunc [T](iter:Iterator[T]):Iterator[(T,T)]={
| var res=List[(T,T)]()
| var pre=iter.next
| while(iter.hasNext){
| val cur=iter.next
| res::=(pre,cur)
| pre=cur}
| res.iterator}
iterfunc: [T](iter: Iterator[T])Iterator[(T, T)]
scala> a.mapPartitions(iterfunc)
res0: org.apache.spark.rdd.RDD[(Int, Int)] = MapPartitionsRDD[1] at mapPartitions at <console>:29
scala> a.mapPartitions(iterfunc).collect()
res1: Array[(Int, Int)] = Array((2,3), (1,2), (5,6), (4,5), (8,9), (7,8))
scala> a.mapPartitions(iterfunc).glom()
res2: org.apache.spark.rdd.RDD[Array[(Int, Int)]] = MapPartitionsRDD[4] at glom at <console>:29
因爲分區中最後一個元素沒有下一個元素,所以(3,4)和(6,7)不在結果中。
collect()和glom()可以把rdd轉換成數組