我有一个CSV文件,我尝试使用Spark CSV package加载它并且它无法正确加载数据,因为其中很少有字段包含if ($user->has('followed')) {
foreach ($user->followed as $followed) {
debug($followed->username);
}
}
,例如以下两行
\n
我正在使用以下代码,这是直截了当的我使用"XYZ", "Test Data", "TestNew\nline", "OtherData"
"XYZ", "Test Data", "blablablabla
\nblablablablablalbal", "OtherData"
作为parserLib
在互联网上阅读它解决了多个换行问题,但对我来说似乎不是这样。
univocity
请指导如何在以引号开头的字段中替换换行符。有没有更简单的方法?
答案 0 :(得分:3)
根据SPARK-14194(已解决为重复),不支持使用新行字符的字段,且不会支持。
我建议通过
wholeFile
选项解决此问题,它似乎已合并。我正在解决这个问题,因为那个人有PR。
然而,Spark 2.0,你使用spark-csv
模块。
在引用的SPARK-19610中,它已使用pull request修复:
嗯,我明白了这个动机,虽然我对csv的理解通常要么避免在字段中使用换行符,要么某些实现需要使用换行符在字段值周围引用
换句话说,在Spark 2.x中使用wholeFile
选项(正如您在CSVDataSource中看到的那样)。
至于spark-csv,this comment可能会有所帮助(突出我的):
但是,有很多类似的JIRA抱怨这个,并且原始的CSV数据源试图支持这一点,尽管这是错误的实现。这至少会尝试将其与JSON配对,最好提供一种处理此类CSV文件的方法。 实际上,当前的实现需要引号 :)。 (有人告诉R实际上支持这个案例)。
在spark-csv' Features中,您可以找到以下内容:
该软件包还支持保存简单(非嵌套)DataFrame。在编写文件时,API接受以下几个选项:
引用:默认情况下,引号字符为
"
,但可以设置为任何字符。这是根据quoteMode
撰写的。quoteMode :何时引用字段(ALL,MINIMAL(默认),NON_NUMERIC,NONE),请参阅引用模式
答案 1 :(得分:2)
Spark 2.2的用户可以选择考虑CSV文件中的换行符。它最初被讨论为被称为wholeFile
但在发布之前被重命名为multiLine
。
以下是使用该选项将CSV加载到数据框的示例:
var webtrends_data = (sparkSession.read
.option("header", "true")
.option("inferSchema", "true")
.option("multiLine", true)
.option("delimiter", ",")
.format("csv")
.load("hdfs://hadoop-master:9000/datasource/myfile.csv"))
答案 2 :(得分:0)
升级到Spark 2.x.换行符实际上是由ascii 13和10表示的CRLF。但反斜杠和' n'是不同的ascii,以编程方式解释和书写。 Spark 2.x将正确读取..我试过它.s.b。
val conf = new SparkConf().setAppName("HelloSpark").setMaster("local[2]")
val sc = SparkSession.builder().master("local").getOrCreate()
val df = sc.read.csv("src/main/resources/data.csv")
df.foreach(row => println(row.mkString(", ")))
如果你不能升级,那么用正则表达式清理RDD上的\ n。这不会删除行尾,因为它是$ in regex。 S.B.
val conf = new SparkConf().setAppName("HelloSpark").setMaster("local")
val sc = new SparkContext(conf)
val rdd1 = sc.textFile("src/main/resources/data.csv")
val rdd2 = rdd1.map(row => row.replace("\\n", ""))
val sqlContext = new SQLContext(sc)
import sqlContext.implicits._
val df = rdd2.toDF()
df.foreach(row => println(row.mkString(", ")))