如何解析使用Apache Spark在数据中包含\ n的CSV?

时间:2018-02-14 09:28:58

标签: scala csv apache-spark

我有一些CSV文件,数据本身有\n个字符。我试图在Apache Spark 2.2中读取这些文件,但Spark无法正确读取数据。

示例数据如下:

column1,column2,column3,column4,...,column300\n
column1,column2,"""this column has \n new line char and comma,",column4,...,column300\n
column1,column2,column3,column4,...,column300\n

如上所示,所有行都以\n字符结尾,而不是\r\n

第二行

  • 有一个列,其中\n和逗号都是数据本身的一部分
  • 列的值以3个双引号开头,以一个双引号
  • 结尾
  • """此列有\ n新行char和逗号,"

我读取此CSV的代码非常简单和标准。

val filePath = "ap-data/lines.csv"
val csv = spark.read.format("csv").option("inferSchema", "true").load(filePath)

我尝试了许多选项,例如option("escape","\n").option("mode", "FAILFAST"),但没有一个选项有效。

Spark将这3行转换为4行,如下所示:

row 1 => column1,column2,column3,column4,...,column300\n
row 2 => column1,column2,"""this column has 
row 3 => new line char and comma,",column4,...,column300\n
row 4 => column1,column2,column3,column4,...,column300\n

实际数据有数百万行,其中\n的所有列都采用相同的格式,即列以3个双引号开头,以一个双引号结尾。

任何人都可以帮助正确解析这类数据吗?

4 个答案:

答案 0 :(得分:1)

您的代码看起来很完美。

我看到的唯一缺陷是

  
    

列的值以3个双引号开头,以一个双引号结束

  

所以你需要将3个双引号替换成1个双引号

我建议您创建临时文件并将代码用作

val filePath = "ap-data/lines.csv"
val tempFilePath = "ap-data/tempLines.csv"
val textrdd = sc.textFile(filePath).map(line => line.replace("\"\"\"", "\"")).saveAsTextFile(tempFilePath)
val csv = spark.read.format("csv").option("inferSchema", "true").load(tempFilePath)

你应该没问题

答案 1 :(得分:1)

有几种可能性。从我看到的结果,第1行,第2行等等,对于第2行,没有换行符。所以你可以做的就是你可以再次遍历行,对于那些没有新行字符的行,将它与下一行连接起来,并继续这样做直到你遇到一个新的行字符!

如果使用Shapeless是一个选项,请查看如何将CSV行打包到案例类中。通过这种方式,您可以摆脱遇到的问题!

https://github.com/joesan/csv-parser/blob/master/src/main/scala/com/inland24/csvparser/CSVParser.scala

答案 2 :(得分:1)

所以最后我得出结论,截至目前Spark还没有处理这种类型的CSV文件。 (不要责怪Spark,我们收到的输入文件中包含无效值)。

所以我编写了自己的自定义记录阅读器,它就像一个魅力。

我借助this blog来编写自定义记录阅读器。希望将来可能对某人有所帮助。

答案 3 :(得分:1)

如果你的spark版本是3,那么试试下面的脚本: pyspark ↓

df = spark.read.format("csv").option("multiline",True).option("delimiter",",").option("header",True).load(DATA_PATH)