我想检查spark中的数据类型并在其后创建两个RDD。一个带有验证记录的RDD和另一个带有错误的RDD。
我正在考虑创建以下方法:
def isInt (value: Any): Option[Int] = {
case value: Int => Some(value)
case _ => None
}
之后我可以根据列调用此方法,如果我得到None,则给出错误,如:
rdd.map{
case(age) => if isInt(age).isEmpty (age,ErrorCodes.NOT_INT) else ((Int)age, None)
}
但我发现这种方法存在两个问题:
还有其他办法吗?
答案 0 :(得分:0)
在不知道上下文的情况下,这种事情的最原则性方法(我想要好的值和错误)可能是创建一个RDD的Either。例如:
import scala.util.{ Either, Left, Right }
case class NotAnInt(obj: Any)
def maybeIntRDD(anyRDD: RDD[Any]): RDD[Either[NotAnInt, Int]] =
anyRDD.map {
case i: Int => Right(i)
case x => Left(NotAnInt(x))
}
val eitherRDD: RDD[Either[NotAnInt, Int]] = maybeIntRDD(rdd)
// Get the ints and not ints
val intRDD: RDD[Int] = eitherRDD.flatMap(_.right.toOption)
val notIntRDD: Rdd[NotAnInt] = eitherRDD.flatMap(_.left.toOption)
// Double the ints, keep the NotAnInts
val doubled: RDD[Either[NotAnInt, Int]] = eitherRDD.map(_.right.map(_ * 2))
如果您有很多列,那么将ValidationFailure特征与一些案例类或案例对象一起扩展该特征可能对于不同类型的失败可能是有用的
def validateRow(row: YourColumnsTypeHere): Either[Seq[ValidationFailure], YourColumnTypeHere] = {
// validation logic here, with errors accumulating in the failures Seq
if (isValid)
Right(row)
else
Left(failures)
}
val classifiedRDD = rdd.map(row => validateRow(row))