RDDの内容を印刷する方法は?


124

コレクションの内容をSparkコンソールに出力しようとしています。

タイプがあります:

linesWithSessionId: org.apache.spark.rdd.RDD[String] = FilteredRDD[3]

そして、私はコマンドを使用します:

scala> linesWithSessionId.map(line => println(line))

しかし、これは印刷されます:

res1:org.apache.spark.rdd.RDD [Unit] =マップされた:19のMappedRDD [4]

RDDをコンソールに書き込んだり、内容を表示できるようにディスクに保存したりするにはどうすればよいですか?


1
こんにちは!あなたはあなたが受け入れた答えのコメントを読みましたか?誤解を招くようです
dk14 '22

2
@ dk14は同意し、承認された回答を再割り当てしました
blue-sky

RDDは2番目のクラスの市民として降格されています。DataFrameとshowメソッドを使用する必要があります。
Thomas Decaux 2017年

回答:


235

RDDのコンテンツを表示したい場合は、次の方法を使用しますcollect()

myRDD.collect().foreach(println)

ただし、RDDに数十億行ある場合、これは良い考えではありません。take()印刷に少しだけ使う:

myRDD.take(n).foreach(println)

1
RDD(数百万行)でforeachを使用してコンテンツをHDFSに単一ファイルとして書き込む場合、クラスターで問題なく動作しますか?
Shankar、

私が使用していない理由saveAsTextFileRDDには、私が使用している理由です複数のファイルの中にRDDのコンテンツを記述する必要が、あるforeach
シャンカール

単一のファイルに保存する場合は、saveAsTextFileを呼び出す前にRDDを1つのパーティションに結合できますが、これでも問題が発生する可能性があります。最良のオプションは、HDFSで複数のファイルに書き込み、次にhdfs dfs --getmergeを使用してファイルをマージすることです
Oussama

RDDでforeachを使用すると、ドライバーのRAMに永続化されると述べましたが、ステートメントは正しいですか?私が理解しているのは、foreachがドライバーではなく各ワーカー[クラスター]で実行されるためです。
シャンカール

saveAsTextFileは、パーティションごとに1つのファイルを書き込みます。これが目的です(複数のファイル)。それ以外の場合は、Oussamaが提案するように、rdd.coalesce(1).saveAsTextFile()を実行して1つのファイルを取得できます。RDDに必要なパーティションが少なすぎる場合は、rdd.repartition(N).saveAsTextFile()を試すことができます
foghorn

49

map関数である変換あなたが実行されるまで、スパークが実際にあなたのRDDを評価しないことを意味し、アクションその上を。

これを印刷するには、次のように使用できますforeach(これはアクションです)。

linesWithSessionId.foreach(println)

ディスクに書き込むにsaveAs...は、RDD APIの関数(まだアクション)の1つを使用できます


6
たぶんcollect、RDDをコンソールで表示できるように言及する必要があります。
zsxwing 2014

1
foreachそれ自体が最初にRDDを「具体化」してprintlnから各要素で実行するため、ここcollectでは実際には必要ありません(もちろん、使用できます)...
fedragon

5
実際にcollect()がないと、foreachの前に、コンソールに何も表示されません。
Vittorio Cozzolino 2014年

3
実際には、1.2.0でも、Sparkシェルで完全に正常に動作します。しかし、私はこの混乱の原因を知っていると思います。元の質問では、RDDをSparkコンソール(=シェル)に出力する方法を尋ねたので、彼はローカルジョブを実行すると仮定しましたforeach。クラスターでジョブを実行していて、rddを印刷したい場合は、collect(他のコメントと回答で指摘されているように)println実行する前にドライバーに送信する必要があります。またtake、RDDが大きすぎる場合は、Oussamaの提案に従って使用することをお勧めします。
fedragon

6
上記の答えは悪いです。受け入れないでください。Foreachはコンソールに出力せず、ワーカーノードに出力します。ノードが1つしかない場合は、foreachが機能します。しかし、ノードが1つしかない場合、なぜSparkを使用するのでしょうか。SQL awk、Grep、またはもっと単純なものを使用してください。だから私は唯一の有効な答えは収集だと思います。収集があなたにとって大きすぎて、サンプルを使用したい場合は、以下に説明するように、テイク関数、ヘッド関数、またはシミラー関数を使用してください。
eshalev 2016

12

これをクラスターで実行している場合printlnは、コンテキストに出力されません。RDDデータをセッションに持ってくる必要があります。これを行うには、強制的にローカル配列にしてから出力します。

linesWithSessionId.toArray().foreach(line => println(line))

12

あなたは、あなたを変換することができますRDDDataFrame、その後show()、それ。

// For implicit conversion from RDD to DataFrame
import spark.implicits._

fruits = sc.parallelize([("apple", 1), ("banana", 2), ("orange", 17)])

// convert to DF then show it
fruits.toDF().show()

これにより、データの上位20行が表示されるため、データのサイズは問題になりません。

+------+---+                                                                    
|    _1| _2|
+------+---+
| apple|  1|
|banana|  2|
|orange| 17|
+------+---+

1
私はそれだと思うimport spark.implicits._
ライアン・ハートマン

ここで使用されたライブラリは何ですか?スパークスコープtoDFも検出もできませんspark.implicits._
セルギ

1

との間にはおそらく多くのアーキテクチャ上の違いがmyRDD.foreach(println)ありますmyRDD.collect().foreach(println)(「収集」だけでなく、他のアクションも)。私が見た違いの1つは、実行myRDD.foreach(println)時に出力がランダムな順序になることです。例:私のrddが各行に番号があるテキストファイルからのものである場合、出力の順序は異なります。しかし、私が行ったときmyRDD.collect().foreach(println)、順序はテキストファイルと同じままです。


1

Pythonで

   linesWithSessionIdCollect = linesWithSessionId.collect()
   linesWithSessionIdCollect

これにより、RDDのすべてのコンテンツが印刷されます


1
ありがとう、しかし私はこの質問にpythonではなくscalaのタグを付けました
blue-sky

1
c.take(10)

そしてSparkの新しいバージョンはテーブルをきれいに表示します。


1

毎回入力する代わりに、次のことができます。

[1] Spark Shell内で汎用の印刷メソッドを作成します。

def p(rdd: org.apache.spark.rdd.RDD[_]) = rdd.foreach(println)

[2]またはさらに良いことに、暗黙を使用して、関数をRDDクラスに追加し、その内容を印刷できます。

implicit class Printer(rdd: org.apache.spark.rdd.RDD[_]) {
    def print = rdd.foreach(println)
}

使用例:

val rdd = sc.parallelize(List(1,2,3,4)).map(_*2)

p(rdd) // 1
rdd.print // 2

出力:

2
6
4
8

重要

これは、ローカルモードで少量のデータセットを使用している場合にのみ意味があります。そうしないと、データセットの結果が大きいために、クライアントで結果を表示できなくなったり、メモリ不足になったりします。



弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.