web-dev-qa-db-ja.com

SparkのRDDで要素の位置を取得するにはどうすればよいですか?

私はApacheSparkを初めて使用し、コアデータ構造がRDDであることを知っています。今、私は要素の位置情報を必要とするいくつかのアプリを書いています。たとえば、ArrayListを(Java)RDDに変換した後、RDDの整数ごとに、その(グローバル)配列の添え字を知る必要があります。それは可能ですか?

ご存知のように、RDDにはtake(int)関数があるので、位置情報はRDDでも維持されていると思います。

12
SciPioneer

基本的に、RDDのzipWithIndex()メソッドはこれを行うように見えますが、RDDが作成されたデータの元の順序は保持されません。少なくとも、安定した注文が得られます。

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

元のデータの順序を保持するものが見つからない可能性が高い理由は、zipWithIndex()のAPIドキュメントに埋め込まれています。

「このRDDを要素インデックスで圧縮します。順序は最初にパーティションインデックスに基づいており、次に各パーティション内のアイテムの順序に基づいています。したがって、最初のパーティションの最初のアイテムはインデックス0を取得し、最後のパーティションの最後のアイテムはインデックス0を受け取ります。最大のインデックス。これはScalaのzipWithIndexに似ていますが、インデックスタイプとしてIntではなくLongを使用します。このメソッドは、このRDDに複数のパーティションが含まれている場合にsparkジョブをトリガーする必要があります。」

そのため、元の注文は破棄されたようです。元の順序を維持することが重要な場合は、インデックスを追加する必要があるようですbefore RDDを作成します。

11
Spiro Michaylov

ほとんどの場合、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つのパーティションがあり、aはインデックス0、bはインデックス1などです。

16
zhang zhan