为什么筛选器默认在 Spark 数据帧上删除空值?



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

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 数据帧具有空安全相等

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

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

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

相关内容

  • 没有找到相关文章

最新更新