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) не работает... CSV, сохраненный в Excel, составляет 1290 байт, в то время как созданный мной CSV (который прекрасно работает) составляет 1292 байта....

ОБНОВЛЕНИЕ 3:

Я открыл два файла, упомянутых в Update2 в vim и заметил, что CSV, сохраненный в Excel, ^M вместо новых строк. Все мои тесты до этого были ошибочными, потому что они всегда сравнивали CSV, изначально сохраненный в Excel, с CSV, созданным из Sublime... Sublime не показывал разницу. Я уверен, что есть настройка или пакет, который я могу установить, чтобы увидеть это, потому что я использую Sublime в качестве моего одноразового редактора файлов...

Не уверен, стоит ли мне закрывать этот вопрос, поскольку название вводит в заблуждение. С другой стороны, должна быть какая-то ценность для кого-то там, лол...

1 ответ

Так как у вопроса есть несколько голосов "за", вот разрешение оригинальной проблемы как ответ...

Новые строки в файлах, сохраненных в мире Windows, содержат как carriage return а также line feed, Spark (работает на Linux) видит это как искаженную строку и отбрасывает ее, потому что в ее мире переводы строки просто line feed,

Уроки:

  • Важно знать происхождение файла, с которым вы работаете.
  • При отладке проблем обработки данных работайте с редактором, который показывает возврат каретки.

Я столкнулся с той же проблемой с опцией multiLine, применяемой к заголовку. Я решил это, добавив дополнительную опцию игнорирования конечных пробелов.

  .option("header", true)
  .option("multiLine", true)
  .option("ignoreTrailingWhiteSpace", true)
Другие вопросы по тегам