Scala 数据集的Spark数据帧空值
从MS SQL数据库导入数据时,可能存在空值。在Spark中,数据帧能够处理空值。但是,当我尝试将数据帧转换为强类型数据集时,会收到编码器错误 下面是一个简单的例子:Scala 数据集的Spark数据帧空值,scala,apache-spark,Scala,Apache Spark,从MS SQL数据库导入数据时,可能存在空值。在Spark中,数据帧能够处理空值。但是,当我尝试将数据帧转换为强类型数据集时,会收到编码器错误 下面是一个简单的例子: case class optionTest(var a: Option[Int], var b: Option[Int]) object testObject { def main(args: Array[String]): Unit = { import spark.implicits._ val df =
case class optionTest(var a: Option[Int], var b: Option[Int])
object testObject {
def main(args: Array[String]): Unit = {
import spark.implicits._
val df = spark.sparkContext.parallelize(Seq(input)).toDF()
val df2 = Seq((1, 3), (3, Option(null)))
.toDF("a", "b")
.as[optionTest]
df2.show()
}
}
以下是这种情况下的错误:
No Encoder found for Any
- field (class: "java.lang.Object", name: "_2")
- root class: "scala.Tuple2"
java.lang.UnsupportedOperationException: No Encoder found for Any
- field (class: "java.lang.Object", name: "_2")
- root class: "scala.Tuple2"
从数据帧创建数据集时,建议采用什么方法来处理可为空的值?如果要使用
选项,则必须对所有记录使用该选项。您还应该使用None
而不是选项(null)
:
问题是您的数据帧与您的案例类不匹配
第一对是(Int,Int)
,第二对是(Int,Option[Null])
要注意的一点是,如果要表示一个选项[Int]
,例如,该值将是Some(3)
,或者对于缺少的值是None
需要注意的是,在ScalaInt
中是AnyVal
的子类,而可空引用(在您编写的Scala代码中几乎不存在)位于Scala对象层次结构的AnyRef
一侧
因为Scala对象模型中有很多对象,Spark必须将数据视为所有事物的超类。没有编码器可以处理这个问题
因此,综上所述,您的数据必须如下所示:
val df2=Seq((部分(1),部分(3)),(部分(3),无))
作为旁注,您的案例类应该如下所示:
case-class OptionTest(a:Option[Int],b:Option[Int])
这很有帮助,但是当转到数据集时,如何处理数据帧中的空值呢?你应该问得很有趣。我早就知道了。
Seq((1, Some(3)), (3, None)).toDF("a", "b").as[optionTest]