2017-09-25 92 views
2

我有其中有一些多线观察一个数据帧:如何处理火花多行的行?

+--------------------+----------------+ 
|   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文件中是同一行。我试图将其保存为txt文件:

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

但是观察到相同的输出。

我可以想象,一种方法是用其他东西替换\n,并且在加载后执行反转功能后。但是有没有一种方法可以在不对数据进行任何形式的转换的情况下以预期的方式进行保存?

回答

2

默认情况下,如果sparkTextFile遇到\ 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) 

在这里,在数据文本是你的分隔符分隔字符串

1

假设多行数据被正确引用,您可以使用单义解析多行CSV数据解析器和多线设置

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

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