私は次のようにPysparkでcsvファイルを読んでいます:
df_raw=spark.read.option("header","true").csv(csv_path)
ただし、データファイルには、コンマが埋め込まれた引用符で囲まれたフィールドがあり、コンマとして扱われるべきではありません。 Pysparkでこれをどのように処理できますか? pandasはこれを処理できますが、Spark?使用できるバージョンはSpark 2.0.0。
Pandasで動作するが、Sparkの使用に失敗する例は次のとおりです。
In [1]: import pandas as pd
In [2]: pdf = pd.read_csv('malformed_data.csv')
In [3]: sdf=spark.read.format("org.Apache.spark.csv").csv('malformed_data.csv',header=True)
In [4]: pdf[['col12','col13','col14']]
Out[4]:
col12 col13 \
0 32 XIY "W" JK, RE LK SOMETHINGLIKEAPHENOMENON#YOUGOTSOUL~BRINGDANOISE
1 NaN OUTKAST#THROOTS~WUTANG#RUNDMC
col14
0 23.0
1 0.0
In [5]: sdf.select("col12","col13",'col14').show()
+------------------+--------------------+--------------------+
| col12| col13| col14|
+------------------+--------------------+--------------------+
|"32 XIY ""W"" JK| RE LK"|SOMETHINGLIKEAPHE...|
| null|OUTKAST#THROOTS~W...| 0.0|
+------------------+--------------------+--------------------+
ファイルの内容:
col1,col2,col3,col4,col5,col6,col7,col8,col9,col10,col11,col12,col13,col14,col15,col16,col17,col18,col19
80015360210876000,11.22,X,4076710258,,,sxsw,,"32 YIU ""A""",S5,,"32 XIY ""W"" JK, RE LK",SOMETHINGLIKEAPHENOMENON#YOUGOTSOUL~BRINGDANOISE,23.0,cyclingstats,2012-25-19,432,2023-05-17,CODERED
61670000229561918,137.12,U,8234971771,,,woodstock,,,T4,,,OUTKAST#THROOTS~WUTANG#RUNDMC,0.0,runstats,2013-21-22,1333,2019-11-23,CODEBLUE
問題のある行に、二重引用符自体を使用するエスケープがあることに気付きました。
"32 XIY" "W" "JK、RE LK"
インタプリタである必要があります
32 XIY "W" JK、RE LK
RFC-418 、2ページで説明されているように-
これは、たとえばデフォルトでExcelが行うことです。
Spark(Spark 2.1)時点)で、エスケープはデフォルトで非RFCの方法でbackslah(\)を使用して行われます。これを修正するには、 Sparkに二重引用符を使用してエスケープ文字として使用するように明示的に指定するには:
.option('quote', '"')
.option('escape', '"')
これは、引用符で囲まれた列内にあるため、コンマ文字が解釈されなかったことを説明する場合があります。
Spark= csv形式のオプションは、Apache Sparkサイトで十分にドキュメント化されていませんが、ここに私はまだ非常に頻繁に役立つ少し古いドキュメントがあります:
https://github.com/databricks/spark-csv
2018年8月更新:Spark 3.0は、この動作をRFC準拠に変更する場合があります。 SPARK- 22236 詳細.
Scalaでこれをしている人にとって:Tagarの答えは私にとってはほとんど役に立ちました(ありがとう!)。私がしなければならなかったのは、オプションパラメータを設定するときに二重引用符をエスケープすることだけでした:
.option("quote", "\"")
.option("escape", "\"")
私はSpark 2.3を使用しているので、Tagarのソリューションは新しいリリースでも同じように動作するようです。
comma
内で指定されたDelimiter(quotes
)は、デフォルトでは無視されます。 Spark= SQLには、Spark 2.0。
df = session.read
.option("header", "true")
.csv("csv/file/path")