Scala 如何在解析过程中获取无效数据的计数
我们正在使用spark解析一个可能包含无效数据的大型csv文件。 我们希望将有效数据保存到数据存储中,并返回导入的有效数据数量和无效数据数量Scala 如何在解析过程中获取无效数据的计数,scala,apache-spark,spark-dataframe,bigdata,Scala,Apache Spark,Spark Dataframe,Bigdata,我们正在使用spark解析一个可能包含无效数据的大型csv文件。 我们希望将有效数据保存到数据存储中,并返回导入的有效数据数量和无效数据数量 spark.read.option("header", "true").csv("/Users/yyuan/jyuan/1.csv").rdd.map ( { row => try { Right("") } catch { case e: Throwable => Left(""); } }).colle
spark.read.option("header", "true").csv("/Users/yyuan/jyuan/1.csv").rdd.map ( { row =>
try {
Right("")
} catch { case e: Throwable => Left(""); }
}).collect()
我想知道如何在spark中做到这一点,读取数据的标准方法是什么
我目前的方法使用的是累加器
,但由于累加器
在spark中的工作方式,它并不准确
// we define case class CSVInputData: all fields are defined as string
val csvInput = spark.read.option("header", "true").csv(csvFile).as[CSVInputData]
val newDS = csvInput
.flatMap { row =>
Try {
val data = new DomainData()
data.setScore(row.score.trim.toDouble)
data.setId(UUID.randomUUID().toString())
data.setDate(Util.parseDate(row.eventTime.trim))
data.setUpdateDate(new Date())
data
} match {
case Success(map) => Seq(map)
case _ => {
errorAcc.add(1)
Seq()
}
}
}
我尝试使用或,但失败,出现异常:
java.lang.NoClassDefFoundError:找不到与可使用scala.util序列化的产品对应的java类。未找到[xx.CSVInputData,xx.DomainData]
更新
我认为这两种方法都不适用于spark 2.0数据集api:
spark.read.option("header", "true").csv("any.csv").map { row =>
try {
Right("")
} catch { case e: Throwable => Left(""); }
}
如果我们改为使用sc(rdd api),它可以:
sc.parallelize('a' to 'z').map { row =>
try {
Right("")
} catch { case e: Throwable => Left(""); }
}.collect()
在当前最新的scala中:两者都没有实现可序列化特性
sealed abstract class Either[+A, +B] extends AnyRef
在未来的2.12中,它会:
sealed abstract class Either[+A, +B] extends Product with Serializable
使用变通方法更新了第2版
更多信息请访问
由于spark dataset两者都不能使用,因此解决方法是调用ds.rdd,然后使用try left right捕获有效和无效数据
spark.read.option("header", "true").csv("/Users/yyuan/jyuan/1.csv").rdd.map ( { row =>
try {
Right("")
} catch { case e: Throwable => Left(""); }
}).collect()
你有没有考虑过使用
您尝试过Spark DDQ吗?它有您需要的大多数数据质量规则。您甚至可以扩展和自定义它
链接:感谢您的回复,我确实尝试使用了其中之一,但它抛出了java.lang.NoClassDefFoundError:没有对应于产品的java类,该产品可通过scala.util.Orit[xx.CSVInputData,xx.DomainData]序列化发现您可能需要使用Kyro序列化:import spark.implicits.\uimplicit val domainDataEncoder=org.apache.spark.sql.Encoders.kryo[DomainData]我认为旧的RDD相关api可以使用其中任何一个,但spark 2.0数据集api都不能使用。请在来源问题中检查我的更新。感谢找到解决dataset api问题的方法-只需调用dataset.rdd,然后使用try catch left right。它起作用了。非常感谢您的帮助。您没有将绩效处罚转化为RDD吗?从理论上讲,这是比较慢的。