mapPartitions返回空数组

时间:2015-08-17 02:55:51

标签: apache-spark rdd

我有以下RDD,它有4个分区: -

val rdd=sc.parallelize(1 to 20,4)

现在我尝试在这上面调用mapPartitions: -

scala> rdd.mapPartitions(x=> { println(x.size); x }).collect
5
5
5
5
res98: Array[Int] = Array()

为什么它返回空数组? anonymoys函数只是返回它收到的相同迭代器,那么它是如何返回空数组的呢?有趣的是,如果我删除println语句,它确实返回非空数组: -

scala> rdd.mapPartitions(x=> { x }).collect
res101: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)

我不明白。为什么println(只是打印迭代器的大小)的存在会影响函数的最终结果?

2 个答案:

答案 0 :(得分:10)

那是因为xTraversableOnce,这意味着您通过调用size遍历它然后将其返回....空。

你可以通过多种方式解决这个问题,但这里有一个:

rdd.mapPartitions(x=> {
  val list = x.toList;
  println(list.size);
  list.toIterator
}).collect

答案 1 :(得分:1)

要了解发生了什么,我们必须查看您传递给mapPartitions的函数的签名:

(Iterator[T]) ⇒ Iterator[U]

那么Iterator是什么?如果您查看Iterator documentation,我会看到它是一个延伸TraversableOnce的特征:

trait Iterator[+A] extends TraversableOnce[A]

上面应该给你一个暗示你的情况会发生什么。迭代器提供两种方法hasNextnext。要获得迭代器的size,您必须简单地迭代它。在hasNext返回false之后,结果会显示空Iterator