2017-12-04 6 views
1

S3バケットからPySpark DataFrameに一連のJSONファイルを取得する際に助けが必要です。複数のJSONオブジェクトを1行のファイルでPySparkに読み込むときのヌル値

このバケットのファイルはすべて、拡張子が.jsonですが、残念ながら通常のSparkでは1行に1つのJSONオブジェクトが必要ですが、大括弧で囲まれた1行になります。

ので、代わりの:

{"first_column": 12, "second_column": {"nested_column": "value"}} 
{"first_column": 24, "second_column": {"nested_column": "value2"}} 

私が持っている:

[{"first_column": 12, "second_column": {"nested_column": "value"}},{"first_column": 24, "second_column": {"nested_column": "value2"}}] 

私たちは、実際にこの形式のファイルを受信し、いずれかを作ることは不可能であることを、それらの多くがあります残念なことに手動調整。私は一度に複数のファイルをロードするためにワイルドカード*で次の構文を使用して、spark.read.jsonメソッドを使用しようとした

次のように私が試してみました

アプローチはこれまでのところです。この場合、sparksqlContext

df = spark.read.json("s3://path_to_bucket_*.json") 

ですこれはエラーや警告を上げることなく実行され、必要なスキーマを返します。私は、データを表示しようとすると

df.printSchema() 

root 
|-- first_column: long (nullable = true) 
|-- second_column: struct (nullable = true) 
|  |-- nested_column: string (nullable = true) 

はしかし、私は以下のようになります。私は実際にスパークコンテキストを使用していますDatabricks hereからのデータをロードする方法を発見した

+------------+-------------+ 
|first_column|second_column| 
+------------+-------------+ 
|  null|   null| 
+------------+-------------+ 

dfRDD = sc.wholeTextFiles("s3://path_to_bucket_*.json") 

これはファイル名でPairedRDDを返し、ファイル本体:は、次のようにペアRDDで読み取ります。しかし、本当に私を混乱されていないものを、私は、このRDDから身体情報を使用して次の行を呼び出すときに、それが正常に動作していることで、NULL値が全く存在しない。

df = spark.read.json(dfRDD.map(lambda x: x[1])) 

だから、私はのような非常に混乱していますなぜこれが起こっているのか、これは、RDD内のテキストの本文に改行が含まれていないので、関数に入力されたのと同じ情報で、代わりに角括弧内にJSONオブジェクトが含まれている私は上に示した例)。

これは回避策ですが、残念ながら欠落しています。まず第一に、RDDメソッドを使うのがはるかに遅く、もっと重要なのは、私がこの情報を入手したファイルの名前の列を取得する必要があることです。ファイルから直接ロードするときにpyspark.sql.functionsモジュールのinput_file_name機能を使用してこれが可能であることはわかっていますが、RDD方式を使用すると機能しません。私は、各pairedRDDの最初の要素からJSON文字列にファイル名情報を取得する純粋なPython関数を書きましたが、これは非常に遅いです。

誰もがこれで私を助けることができるなら、私は非常に感謝します。私はRDD方法を使わなければならないかもしれないことを感謝しますが、なぜspark.read.jsonが完璧に1つの状況で動作し、他の状況では動作しないのか混乱しています。

答えて

1

私は1つの解決策が動作する原因と考えられないことがわかりませんが、sql.read.jsonを使用するだけで問題をある程度解決できました。

パラメータallowComments、allowUnquotedFieldNames、allowSingleQuotes、allowNumericLeadingZero、allowBackslashEscapingAnyCharacter in trueをread.jsonに設定します。これにより、null値を削除することができ、データの90%がnull値なしのデータフレームで正常に変換されました。

他のパラメータを確認してくださいhere

+0

これに遅れて返答して申し訳ありません。私は今これを実装しようとしましたが、残念ながらNULLレコードを取得しています。しかし、私は問題を引き起こしている別の問題に気付いた。 'mode'パラメータを' 'FAILFAST ''に設定すると、テキスト中のいくつかの文字のためにUnicodeエラーが発生します。ただし、 'wholeTextFiles'メソッドを使用している場合は表示されません。私は今それが追加の問題を引き起こしているのだろうかと思っています。 –

+0

はいwholeTextFilesが無視するこれらの文字のために、レコードが壊れていると宣言される可能性があります。文字を一度削除してみてください。私はこれがうまくいくと思います。 –

関連する問題