[英]Spark DataFrame nulls to Dataset
從MS SQL數據庫導入數據時,可能會出現空值。 在Spark中,DataFrames可以處理空值。 但是,當我嘗試將DataFrame轉換為強類型的Dataset時,會收到編碼器錯誤。
這是一個簡單的例子:
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創建數據集時,推薦的處理空值的方法是什么?
問題在於您的數據框與案例類不匹配。
您的第一對是(Int, Int)
,第二對是(Int, Option[Null])
。
容易注意到的是,如果要表示Option[Int]
,則該值將為Some(3)
,而對於缺少的值將為None
。
需要注意的棘手的事情是,在Scala中, Int
是AnyVal
的子類,而在您編寫的Scala代碼中應該幾乎不存在的可空引用位於Scala對象層次結構的AnyRef
端。
由於您在Scala對象模型中遍布一堆對象,因此Spark必須將您的數據視為Any
,這是一切的超類。 沒有編碼器可以處理該問題。
所以說了這么多,您的數據就必須像這樣:
val df2 = Seq((Some(1), Some(3)), (Some(3), None))
作為附帶說明,您的案例類應如下所示:
case class OptionTest(a: Option[Int], b: Option[Int])
如果要使用Option
,則必須將其用於所有記錄。 您還應該使用None
而不是Option(null)
:
Seq((1, Some(3)), (3, None)).toDF("a", "b").as[optionTest]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.