【发布时间】:2019-07-05 07:53:55
【问题描述】:
我是初学者使用 scala 学习 spark .pardon 为我的英语不好...我需要编写一个程序来使用 spark-scala Dataframe Api 将分隔和固定宽度的文件解析为 Dataframe。此外,如果输入数据已损坏,则程序必须按以下给定方式处理:
A:ignoring the input data
B:investigate the error in input
C:stop on error
为了实现上述目标,我已经使用 DataFrame Api 选项成功完成了对分隔文件的异常处理解析。但我不知道如何对固定宽度文件应用相同的技术。我使用的是 Spark 2.4.3 版本。
// predefined schema used in program
val schema = new StructType()
.add("empno",IntegerType,true)
.add("ename",StringType,true)
.add("designation",StringType,true)
.add("manager",StringType,true)
.add("hire_date",StringType,true)
.add("salary",DoubleType,true)
.add("deptno",IntegerType,true)
.add("_corrupt_record", StringType, true)
// parse csv file into DataFrame Api
// option("mode","PERMISSIVE") used to handle corrupt record
val textDF =sqlContext.read.format("csv").option("header", "true").schema(schema).option("mode", "PERMISSIVE").load("empdata.csv")
textDF.show
// program for fixed width line
// created lsplit method to split line into list of tokens based on width input / string
def lsplit(pos: List[Int], str: String): List[String] = {
val (rest, result) = pos.foldLeft((str, List[String]())) {
case ((s, res),curr) =>
if(s.length()<=curr)
{
val split=s.substring(0).trim()
val rest=""
(rest, split :: res)
}
else if(s.length()>curr)
{
val split=s.substring(0, curr).trim()
val rest=s.substring(curr)
(rest, split :: res)
}
else
{
val split=""
val rest=""
(rest, split :: res)
}
}
// list is reversed
result.reverse
}
// create case class to hold parsed data
case class EMP(empno:Int,ename:String,designation:String,manager:String,hire_dt:String,salary:Double,deptno:Int)
// create variable to hold width length
val sizeOfColumn=List(4,4,5,4,10,8,2);
// code to transform string to case class record
val ttRdd=textDF.map {
x =>
val row=lsplit(sizeOfColumn,x.mkString)
EMP(row(0).toInt,row(1),row(2),row(3),row(4).toDouble,row(5).toInt)
}
Code works fine for proper data but fails if incorrect data comes in file.
for e.g: "empno" column has some non-integer data..program throws exception NumberFormatException..
The program must handle if actual data in file does not match the specified schema as handled in delimited file.
请在这里帮助我。我需要对固定宽度文件使用与分隔文件相同的方法。
【问题讨论】:
-
那么如果长度不正确一定会产生错误?
-
B是什么意思?
-
我的意思是如果输入文件中的实际数据与模式不匹配......我们可以看到我正在将一个字段的数据转换为双精度,但如果输入非数字字符则程序失败......同样是Dataframe Api 使用 mode="PERMISSIVE" 在分隔的情况下处理......但我找不到固定宽度文件的相同......
-
B 意味着损坏的记录被复制到 _corrupt_column ......所以我可以调查为什么首先发生错误......
-
但这应该会发生,有趣
标签: scala apache-spark