我的CSV文件如下:
"a","b","c","{""x"":""xx"",""y"":""yy""}"
当我使用java CSV阅读器(au.com.bytecode.opencsv.CSVParser
)时,它会在我指示defaultEscapeChar = '\u0000'
当我尝试使用spark 2.2 CSV阅读器阅读时,它失败了,无法将其拆分为4列。这就是我试过的:
val df = spark.read.format("csv")
.option("quoteMode","ALL")
.option("quote", "\u0000")
.load("s3://...")
我也尝试option("escape", "\u0000")
但没有运气。
我需要选择哪些CSV选项才能正确解析此文件?
答案 0 :(得分:2)
你实际上很接近,正确的选项是option("escape", "\"")
所以考虑到最近的火花版本(2.2+或甚至更早),下面的片段
import org.apache.spark.sql.{Dataset, SparkSession}
object CsvJsonMain {
def main(args: Array[String]): Unit = {
val spark = SparkSession.builder().appName("CsvJsonExample").master("local").getOrCreate()
import spark.sqlContext.implicits._
val csvData: Dataset[String] = spark.sparkContext.parallelize(List(
"""
|"a","b","c","{""x"":""xx"",""y"":""yy""}"
""".stripMargin)).toDS()
val frame = spark.read.option("escape", "\"").csv(csvData)
frame.show()
}
}
会产生
+---+---+---+-------------------+
|_c0|_c1|_c2| _c3|
+---+---+---+-------------------+
| a| b| c|{"x":"xx","y":"yy"}|
+---+---+---+-------------------+
spark无法解析这样的csv开箱即用的原因是默认的转义值是' \'在CSVOptions的第91行可以看到符号,它显然无法使用默认的json引号转义。
它曾经在使用databricks-csv库的spark 2.0之前工作的根本原因是底层的csv引擎曾经是commons-csv并且转义字符默认为null将允许库检测json及其#s; s逃避的方式。由于2.0 csv功能是火花本身的一部分,并且使用uniVocity CSV parser并没有提供这样的"魔法"但显然速度更快。
P.S。如果要保留json数据,请不要忘记在编写csv文件时指定转义。
frame.write.option("quoteAll","true").option("escape", "\"").csv("csvFileName")
答案 1 :(得分:-1)
我在Spark 1.6上使用Spark CSV作为外部JAR,但这对我有用:
sqlContext.read.format("com.databricks.spark.csv")
.option("quoteMode", "ALL")
.option("delimiter", ",")
.load("file")
.show
+---+---+---+-------------------+
| C0| C1| C2| C3|
+---+---+---+-------------------+
| a| b| c|{"x":"xx","y":"yy"}|
+---+---+---+-------------------+
编辑:看起来Spark CSV足够智能
sc.textFile("file").collect
res7: Array[String] = Array(a,b,c,"{""x"":""xx"",""y"":""yy""}")
scala> sqlContext.read.format("com.databricks.spark.csv").load("file").show
+---+---+---+-------------------+
| C0| C1| C2| C3|
+---+---+---+-------------------+
| a| b| c|{"x":"xx","y":"yy"}|
+---+---+---+-------------------+
scala> sqlContext.read.format("com.databricks.spark.csv").option("quoteMode", "ALL").load("file").show
+---+---+---+-------------------+
| C0| C1| C2| C3|
+---+---+---+-------------------+
| a| b| c|{"x":"xx","y":"yy"}|
+---+---+---+-------------------+