考虑以下DataFrame
root
|-- values: array (nullable = true)
| |-- element: double (containsNull = true)
内容:
+-----------+
| values|
+-----------+
|[1.0, null]|
+-----------+
现在我想将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
我的问题:
foreach(println)
没有提供与foreach(d=>println(d))
相同的输出?Double
在第一个println语句中为null,我认为scala的Double
不能为空?Seq
其他han过滤0.0
中过滤掉那些不安全的空值?我应该在UDF中使用Seq[java.lang.Double]
作为输入的类型,然后过滤空值吗? (这有效,但我不确定这是否可行)请注意,我知道this Question,但我的问题是针对数组类型的列。
答案 0 :(得分:1)
为什么foreach(println)没有提供与foreach相同的输出(d => println(d))?
在期望Any
的上下文中,完全跳过数据转换。这在If an Int can't be null, what does null.asInstanceOf[Int] mean?
在第一个println语句中Double如何为null,我认为scala的Double不能为空?
内部二进制表示根本不使用Scala类型。解码数组数据后,它表示为Array[Any]
,元素被强制转换为简单asInstanceOf
的声明类型。
我应该在UDF中使用Seq [java.lang.Double]作为输入的类型,然后过滤空值吗?
通常,如果值可以为空,那么您应该使用可以为空的外部类型或Option
。不幸的是,只有第一个选项适用于UDF。