【问题标题】:Spark fails to read CSV when last column name contains spaces最后一列名称包含空格时,Spark 无法读取 CSV
【发布时间】:2018-11-01 19:44:39
【问题描述】:

我有一个如下所示的 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 作为我的首选一次性文件编辑器......

由于标题具有误导性,我不确定是否应该关闭此问题。再说一次,对外面的人来说一定有一些价值哈哈......

【问题讨论】:

  • 我在没有架构的情况下进行了测试,它运行良好。那你能分享一下架构吗?
  • StructType(Array(StructField("Column One", StringType, true), StructField("Column Two", StringType, true), StructField("Column Three", StringType, true)))
  • 它对我有用。你正在开发的 spark 和 scala 版本是什么?
  • @LXXIII 您使用的是哪个 spark 版本?因为在 Spark v2.3.0 中,您的代码运行良好。
  • @himanshuIIITian 2.2.0。当然,我为这篇文章简化了我的代码。但现在我意识到,我应该在发布之前测试这个简化的代码,如果它有效,消除差异,直到真正的问题冒出来。好的。我有一些迭代要做哈哈。

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


【解决方案1】:

由于该问题有一些赞成票,因此将原始问题的解决方案作为答案...

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

课程:

  • 熟悉您正在使用的文件的来源非常重要。
  • 调试数据处理问题时,使用显示回车的编辑器。

【讨论】:

    【解决方案2】:

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

      .option("header", true)
      .option("multiLine", true)
      .option("ignoreTrailingWhiteSpace", true)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-08
      • 2015-06-03
      • 2013-06-02
      • 2021-11-22
      相关资源
      最近更新 更多