当最后一个列名称包含空格时,Spark无法读取CSV

时间:2018-05-22 23:33:37

标签: scala csv apache-spark apache-commons spark-csv

我的CSV看起来像这样:

+-----------------+-----------------+-----------------+
| Column One      | Column Two      | Column Three    |
+-----------------+-----------------+-----------------+
| This is a value | This is a value | This is a value |
+-----------------+-----------------+-----------------+
| This is a value | This is a value | This is a value |
+-----------------+-----------------+-----------------+
| This is a value | This is a value | This is a value |
+-----------------+-----------------+-----------------+

在纯文本中,它实际上是这样的:

Column One,Column Two,Column Three
This is a value,This is a value,This is a value
This is a value,This is a value,This is a value
This is a value,This is a value,This is a value

我的spark.read方法如下所示:

val df = spark.read
    .format("csv")
    .schema(schema)
    .option("quote", "\"")
    .option("escape", "\"")
    .option("header", "true")
    .option("multiLine", "true")
    .option("mode", "DROPMALFORMED")
    .load(inputFilePath)

multiLine设置为true时,df会加载为空。当multiLine设置为false时,它会正常加载,但我需要将multiLine设置为true

如果我将Column Three的名称更改为ColumnThree,并在schema对象中更新该名称,那么它可以正常工作。似乎multiLine正在应用于标题行!我希望header也设置为true时不会出现这种情况。

任何想法如何解决这个问题?我应该使用univocity解析器而不是默认的commons吗?

更新:

我不知道为什么嘲笑数据工作正常。这里是数据的更近代表:

CSV(只有1个标题和1行数据......):

Digital ISBN,Print ISBN,Title,Price,File Name,Description,Book Cover File Name
97803453308,test,This is English,29.99,qwe_1.txt,test,test

架构& spark.read方法:

val df = spark.read
  .format("csv")
  .schema(StructType(Array(
    StructField("Digital ISBN", StringType, true),
    StructField("Print ISBN", StringType, true),
    StructField("Title", StringType, true),
    StructField("File Name", StringType, true),
    StructField("Price", StringType, true),
    StructField("Description", StringType, true),
    StructField("Book Cover File Name", StringType, true)
  )))
  .option("quote", "\"")
  .option("escape", "\"")
  .option("header", "true")
  .option("multiLine", "true")
  .option("mode", "DROPMALFORMED")
  .load(inputFilePath)

df.show()会产生spark-shell

+------------+----------+-----+---------+-----+-----------+--------------------+
|Digital ISBN|Print ISBN|Title|File Name|Price|Description|Book Cover File Name|
+------------+----------+-----+---------+-----+-----------+--------------------+
+------------+----------+-----+---------+-----+-----------+--------------------+

UDPATE 2:

我想我找到了"与众不同的"。当我复制CSV中的数据并将其保存到另一个CSV时,它可以正常工作。但原始CSV(由Excel保存)失败... Excel保存的CSV为1290字节,而我自己创建的CSV(工作正常)为1292字节....

更新3:

我打开了vim中Update2中提到的两个文件,发现Excel保存的CSV有^M而不是新行。我之前的所有测试都存在缺陷,因为它总是比较最初由Excel保存的CSV与从Sublime创建的CSV ... Sublime没有显示差异。我确定我可以安装一个设置或软件包来查看,因为我使用Sublime作为我的首选一次性文件编辑器......

由于标题具有误导性,我不确定是否应该关闭此问题。再说一遍,那里的某些人必须有一些价值大声笑......

2 个答案:

答案 0 :(得分:1)

由于该问题有几票赞成票,因此以下是对原始问题的解决方案作为答案...

在Windows世界中保存的文件中的换行符同时包含carriage returnline feed。 Spark(在Linux上运行)将其视为格式错误的行并将其删除,因为在现实世界中,换行符只是line feed

课程:

  • 熟悉所使用文件的来源很重要。
  • 调试数据处理问题时,请使用显示回车符的编辑器。

答案 1 :(得分:0)

我遇到了同样的问题,将multiLine选项应用于标题。我通过添加忽略尾随空格的附加选项解决了该问题。

  .option("header", true)
  .option("multiLine", true)
  .option("ignoreTrailingWhiteSpace", true)
相关问题