2017-02-26 77 views
0

考慮下面的數據幀如何篩選可空陣列的元素星火1.6 UDF

root 
|-- values: array (nullable = true) 
| |-- element: double (containsNull = true) 

與內容:

+-----------+ 
|  values| 
+-----------+ 
|[1.0, null]| 
+-----------+ 

現在我想thie value列傳遞到UDF:

val inspect = udf((data:Seq[Double]) => { 
    data.foreach(println) 
    println() 
    data.foreach(d => println(d)) 
    println() 
    data.foreach(d => println(d==null)) 
    "" 
}) 

df.withColumn("dummy",inspect($"values")) 

我真的很迷惑上面println的陳述輸出:

1.0 
null 

1.0 
0.0 

false 
false 

我的問題:

  1. 爲什麼foreach(println)不給輸出foreach(d=>println(d))一樣嗎?
  2. Double如何在第一個println語句中爲null,我認爲scala的Double不能爲null?
  3. 如何過濾我的Seq其他漢氏過濾中的空值0.0這真的不安全?我應該使用Seq[java.lang.Double]作爲UDF中輸入的類型,然後過濾空值? (這個工作,但我不能確定這是要走的路)

請注意,我所知道的this Question,但我的問題是特定於數組類型的列。

回答

1

爲什麼foreach(println)沒有給出與foreach相同的輸出(d => println(d))?

在期望Any預計數據轉換完全跳過的上下文中。這在詳細If an Int can't be null, what does null.asInstanceOf[Int] mean?

解釋了雙怎麼能爲空在第一的println語句,我認爲Scala的雙重不能爲空?

內部二進制表示根本不使用Scala類型。一旦陣列數據被解碼,它被表示爲Array[Any],並且元素被強制爲具有簡單的asInstanceOf的聲明類型。

我應該在UDF中使用Seq [java.lang.Double]作爲輸入的類型,然後過濾空值?

一般來說,如果值是可以爲空的,那麼您應該使用可爲空的外部類型或Option。不幸的是,只有第一種選擇適用於UDF。