Spark DataFrame为数据集空值

时间:2017-03-31 00:03:42

标签: scala apache-spark

从MS SQL数据库导入数据时,可能存在空值。在Spark中,DataFrames能够处理空值。但是当我尝试将DataFrame转换为强类型数据集时,我收到编码器错误。

这是一个简单的例子:

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"

从DataFrame创建数据集时,建议处理可为空值的方法是什么?

2 个答案:

答案 0 :(得分:1)

问题是您的Dataframe与您的案例类不匹配。

您的第一对是(Int, Int),第二对是(Int, Option[Null])

要注意的一件事是,如果您想要代表Option[Int],则该值将为Some(3),例如,或None表示缺席值。

需要注意的棘手问题是,Scala IntAnyVal的子类,而可编写的引用(在您编写的Scala代码中几乎不存在)位于AnyRef Scala对象层次结构的一面。

因为你有大量的对象遍布Scala对象模型,所以Spark必须将你的数据视为Any,即所有内容的超类。没有可以处理的编码器。

所有这些说明,您的数据必须如下所示:

val df2 = Seq((Some(1), Some(3)), (Some(3), None))

作为旁注,您的案例类应如下所示:

case class OptionTest(a: Option[Int], b: Option[Int])

答案 1 :(得分:0)

如果您想使用Option,则必须将其用于所有记录。您还应该使用None代替Option(null)

Seq((1, Some(3)), (3, None)).toDF("a", "b").as[optionTest]