为什么过滤器在spark数据帧上默认删除空值?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么过滤器在spark数据帧上默认删除空值?相关的知识,希望对你有一定的参考价值。

包含filter值的基本scala集合上的null具有以下(并且非常直观)行为:

scala> List("a", "b", null).filter(_ != "a")
res0: List[String] = List(b, null)

但是,我很惊讶地发现以下过滤器删除了spark数据帧中的空值:

scala> val df = List(("a", null), ( "c", "d")).toDF("A", "B")
scala> df.show
+---+----+
|  A|   B|
+---+----+
|  a|null|
|  c|   d|
+---+----+
scala> df.filter('B =!= "d").show
+---+---+
|  A|  B|
+---+---+
+---+---+

如果我想保持null值,我应该补充

df.filter('B =!= "d" || 'B.isNull).show
+---+----+
|  A|   B|
+---+----+
|  a|null|
+---+----+

就个人而言,我认为默认情况下删除空值非常容易出错。为什么选择这个?为什么在api文档中没有明确说明?我错过了什么吗?

答案

这是因为SQL的标准不是空安全的 - 所以Spark SQL遵循这个(但不是Scala)。

Spark数据帧具有null安全相等性

scala> df.filter($"B" <=> null).show
+---+----+
|  A|   B|
+---+----+
|  a|null|
+---+----+


scala> df.filter(not($"B" <=> "d")).show
+---+----+
|  A|   B|
+---+----+
|  a|null|
+---+----+

编辑时注意:默认情况下,不安全的点是允许测试结果为null。缺失值是否等于“c”?我们不知道。缺失值是否等于另一个缺失值?我们也不知道。但在过滤器中,null为false。

以上是关于为什么过滤器在spark数据帧上默认删除空值?的主要内容,如果未能解决你的问题,请参考以下文章

Spark:在scala中的数据帧上使用动态过滤器进行聚合

带有包含地图的数组的数据帧上的 Spark 过滤器

cast方法导致java spark中的空值

Spark数据框过滤空值和空格

Spark中转换的失败处理

Pyspark SQL:在数据透视表中保留只有空值的条目