使用包含嵌入逗号的引用字段读取csv文件

fem*_*yte 21 csv apache-spark apache-spark-sql pyspark apache-spark-2.0

我正在Pyspark中读取一个csv文件,如下所示:

df_raw=spark.read.option("header","true").csv(csv_path)
Run Code Online (Sandbox Code Playgroud)

但是,数据文件引用了带有嵌入式逗号的字段,不应将其视为逗号.我如何在Pyspark处理这个问题?我知道熊猫可以解决这个问题,但是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|
+------------------+--------------------+--------------------+
Run Code Online (Sandbox Code Playgroud)

文件内容:

    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
Run Code Online (Sandbox Code Playgroud)

Tag*_*gar 33

我注意到你的有问题的行已经转义,它使用双引号本身:

"32 XIY""W""JK,RE LK"

这应该是解释者

32 XIY"W"JK,RE LK

RFC-4180第2页所述 -

  1. 如果使用双引号括起字段,那么出现在字段内的双引号必须通过在其前面加上另一个双引号来转义

这就是Excel所做的,例如,默认情况下.

虽然在Spark中(从Spark 2.1开始),默认情况下使用backslah(\)通过非RFC方式进行转义.要解决此问题,您必须明确告诉Spark使用doublequote作为转义字符:

.option('quote', '"')
.option('escape', '"')
Run Code Online (Sandbox Code Playgroud)

这可以解释为逗号字符未被解释为在引用列中.

Spark csv格式的选项在Apache Spark站点上没有很好地记录,但是这里有一些较旧的文档,我仍然经常发现它很有用:

https://github.com/databricks/spark-csv

更新2018年8月:Spark 3.0可能会将此行为更改为RFC投诉.有关详细信息,请参见SPARK-22236.


小智 23

对于在Scala中这样做的人:Tagar的答案几乎对我有用(谢谢!); 我所要做的就是在设置我的选项参数时逃避双引号:

.option("quote", "\"")
.option("escape", "\"")
Run Code Online (Sandbox Code Playgroud)

我正在使用Spark 2.3,所以我可以确认Tagar的解决方案似乎在新版本下仍然有效.


小智 13

对于那些仍然想知道使用 Tagar 的解决方案后解析是否仍然无法工作的人。

Pyspark 3.1.2 .option("quote", "\"") 是默认值,所以这不是必需的,但是在我的情况下,我有多行数据,因此 Spark 无法\n在单个数据点和每行末尾自动检测,因此使用.option("multiline", True)解决了我的问题,.option('escape', "\"")所以通常最好默认使用多行选项


mrs*_*vas 1

comma默认情况下,内部指定的Delimiter( )quotes将被忽略。Spark SQL 在 Spark 2.0 中确实有内置的 CSV 读取器。

df = session.read
  .option("header", "true")
  .csv("csv/file/path")
Run Code Online (Sandbox Code Playgroud)

有关 CSV 阅读器的更多信息,请参见此处 -

  • 这似乎不起作用。请参阅我上面提供的示例。 (4认同)