如何处理spark中的多行行?

时间:2017-09-25 15:08:48

标签: scala apache-spark

我的数据框有一些多行观察结果:

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

 row               |     somethings|
|something            |somethingall    |

我想要的是以csv格式(或txt)保存此数据帧。使用以下内容:

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

但是当我检查文件时,它会将观察结果分成多行。我想要的是将'multiline'observatios作为txt / csv文件中同一行的行。我试图将其保存为txt文件:

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

但观察到相同的输出。

我可以想象,一种方法是用其他东西替换\n,然后在加载时执行反向功能。但有没有办法以理想的方式保存它而不对数据进行任何转换?

2 个答案:

答案 0 :(得分:4)

假设正确引用了多行数据,您可以使用univocity解析器和multiLine设置解析多行csv数据

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

请注意,这需要将整个文件作为单个执行程序读取,如果数据太大,则可能无效。标准文本文件读取将在执行任何其他解析之前按行分割文件,这将阻止您使用包含换行符的数据记录,除非您可以使用不同的记录分隔符。如果不是,您可能需要实现自定义TextInputFormat来处理多行记录。

答案 1 :(得分:2)

默认情况下,如果遇到\ n,则save saveTextFile会考虑不同的行。这与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)

这里的数据Text是分隔符分隔的字符串