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

问题描述 投票:0回答:5

我正在 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
csv apache-spark pyspark apache-spark-sql apache-spark-2.0
5个回答
109
投票

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

“32 XIY”“W”“JK,RE LK”

应该是口译员,就像

32 XIY“W”JK,RE LK

RFC-4180,第 2 页所述 -

  1. 如果使用双引号来括住字段,则必须通过在字段前添加另一个双引号来转义出现在字段内的双引号

这就是 Excel 的默认做法。

尽管在 Spark 中(从 Spark 2.1 开始),转义默认是通过非 RFC 方式使用反斜杠 (\) 完成的。要解决此问题,您必须明确告诉 Spark 使用双引号作为转义字符:

.option("quote", "\"")
.option("escape", "\"")

这可能解释了逗号字符未正确解释,因为它位于带引号的列中。

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

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

2018 年 8 月更新:Spark 3.0 可能会更改此行为以使其符合 RFC 标准。有关详细信息,请参阅 SPARK-22236


52
投票

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

.option("quote", "\"")
.option("escape", "\"")

我正在使用 Spark 2.3,所以我可以确认 Tagar 的解决方案在新版本下似乎仍然可以正常工作。


12
投票

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

Pyspark 3.1.2

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


1
投票
默认情况下,

comma

内指定的
分隔符(
quotes
)将被忽略。 Spark SQL 在 Spark 2.0 中确实有内置的 CSV 读取器。

df = session.read
  .option("header", "true")
  .csv("csv/file/path")

有关 CSV 阅读器的更多信息 - .


0
投票

我遇到了类似的问题,其中 csv 中的值是“感冒,咳嗽”,但在 pyspark 数据框中,它读作“”“感冒,咳嗽””,艾莉·罗杰斯的解决方案有所帮助。

.option("引用", "\"") .option("转义", "\"")

我只是想评论艾莉·罗杰斯的评论,但我没有足够的声誉

© www.soinside.com 2019 - 2024. All rights reserved.