Здесь в тексте данных - строка, разделенная вашим разделителем

я есть датафрейм, который имеет несколько многострочных наблюдений:

+--------------------+----------------+
|         col1|               col2|
+--------------------+----------------+
|something1           |somethingelse1  |
|something2           |somethingelse2  |
|something3           |somethingelse3  |
|something4           |somethingelse4  |
|multiline

 row               |     somethings|
|something            |somethingall    |

Я хочу сохранить вcsv Формат (илиtxt) это датафрейм Используя следующее:

df
 .write
 .format("csv")
 .save("s3://../adf/")

Но когда я проверяю файл, он разделяет наблюдения на несколько строк. Я хочу, чтобы строки с многострочными наблюдениями были одной и той же строкой в ​​файле txt / csv. Я пытался сохранить его как текстовый файл:

df
.as[(String,String)]
.rdd
.saveAsTextFile("s3://../adf")

но такой же выход наблюдался.

Я могу себе представить, что одним из способов является замена\n с чем-то еще и после при загрузке делай обратную функцию. Но есть ли способ сохранить его нужным способом без каких-либо преобразований в данные?

Ответы на вопрос(2)

что многострочные данные правильно указаны в кавычках, вы можете анализировать многострочные данные CSV, используя анализатор однозначности и настройку multiLine.

sparkSession.read
  .option("parserLib", "univocity")
  .option("multiLine", "true")
  .csv(file)

Обратите внимание, что это требует считывания всего файла как одного исполнителя и может не работать, если ваши данные слишком велики. Стандартное чтение текстового файла будет разбивать файл по строкам перед выполнением любого другого анализа, что помешает вам работать с записями данных, содержащими переводы строк, если только вы не можете использовать другой разделитель записей. Если нет, вам может потребоваться реализовать пользовательский TextInputFormat для обработки многострочных записей.

 ghukill30 нояб. 2018 г., 18:23
Это правда? Что весь файл читается одному исполнителю? Я задавался вопросом, было ли это так, поскольку это очень вероятно нарушит ограничения памяти.
 ghukill01 дек. 2018 г., 16:11
спасибо за подтверждение того, что он прочитает весь файл одному исполнителю, это полезно знать (конечно, без специального анализатора).
 puhlen01 дек. 2018 г., 07:48
@ghukill Обычно, когда вы используете однострочный синтаксический анализ, ни один файл не читается и не обрабатывается построчно многими различными исполнителями, поэтому вы можете прекрасно обрабатывать файлы любого размера. В этом конкретном случае, когда вы используете многострочный анализ, весь файл должен быть прочитан одному исполнителю, чтобы он мог согласовать многострочные записи. Я думаю, что было бы возможно написать собственный многострочный TextInputFormat, но, насколько я знаю, в библиотеках по умолчанию ничего не существует, так как это немного специфический крайний случай.

если встречает \ n. Это то же самое с CSV. В чтении CSV вы можете указать разделитель с опцией ("разделитель", "\ t").

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

Что-то вроде этого :

import org.apache.hadoop.io.LongWritable
import org.apache.hadoop.io.Text
import org.apache.hadoop.conf.Configuration
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat

val conf = new Configuration
conf.set("textinputformat.record.delimiter", "<your delimiter>")
val data: RDD[(LongWritable, Text)] =spark.sparkContext.newAPIHadoopFile(<"filepath">, classOf[TextInputFormat], classOf[LongWritable], classOf[Text], conf)

Здесь в тексте данных - строка, разделенная вашим разделителем

Ваш ответ на вопрос