如何在Spark的RDD中获取元素位置?

时间:2014-09-25 19:19:08

标签: position apache-spark rdd

我是Apache Spark的新手,我知道核心数据结构是RDD。现在我正在编写一些需要元素位置信息的应用程序。例如,在将ArrayList转换为(Java)RDD之后,对于RDD中的每个整数,我需要知道它的(全局)数组下标。有可能吗?

据我所知,RDD有一个 take(int)函数,所以我相信位置信息仍然保留在RDD中。

2 个答案:

答案 0 :(得分:14)

我相信在大多数情况下,zipWithIndex()会做到这一点,它会保留顺序。再次阅读评论。我的理解是它确实意味着保持RDD中的顺序。

scala> val r1 = sc.parallelize(List("a", "b", "c", "d", "e", "f", "g"), 3)
scala> val r2 = r1.zipWithIndex
scala> r2.foreach(println)
(c,2)
(d,3)
(e,4)
(f,5)
(g,6)
(a,0)
(b,1)

上面的例子证实了这一点。红色有3个分区,索引为0,b为索引1,等等。

答案 1 :(得分:11)

基本上,RDD的zipWithIndex()方法似乎这样做,但它不会保留创建RDD的数据的原始顺序。至少你会获得稳定的订购。

val orig: RDD[String] = ...
val indexed: RDD[(String, Long)] = orig.zipWithIndex()

您不太可能找到保留原始数据中顺序的内容的原因隐藏在zip文件的zip文档中:

  

“使用元素索引来拉开此RDD。排序首先基于   在分区索引上,然后是每个项目中的项目顺序   划分。所以第一个分区中的第一个项目得到索引0,和   最后一个分区中的最后一项接收最大索引。这个   类似于Scala的zipWithIndex,但它使用Long而不是Int   索引类型。此方法需要在此RDD时触发spark作业   包含多个分区。“

所以看起来原始订单被丢弃了。如果保留原始顺序对您来说很重要,那么您需要在创建RDD之前添加索引