繁体   English   中英

Spark 数据帧过滤器/其中不适用于多种条件

[英]Spark dataframe filter/where is not working for multiple conditions


val someDF = Seq(
  (8, "bat"),
  (64, "mouse"),
  (-27, "horse"),
  (10, null),
  (11, "")
).toDF("number", "word")


使用上面的数据框,我试图过滤掉空和空的单词列值。

Trail - 1

someDF.filter(col("word") =!= "" || col("word").isNotNull).show(false)
+------+-----+
|number|word |
+------+-----+
|8     |bat  |
|64    |mouse|
|-27   |horse|
|11    |     |
+------+-----+

我已经使用了 OR 条件,但仍然没有删除空字符串单词列值。


Trail - 2

someDF.filter(col("word") =!= "").filter(col("word").isNotNull).show(false)
+------+-----+
|number|word |
+------+-----+
|8     |bat  |
|64    |mouse|
|-27   |horse|
+------+-----+


在 trail - 2 中,我使用了链过滤器,然后它从数据框中删除了空值和空值。


Trail - 3


someDF.filter(col("word") =!= "" && col("word").isNotNull).show(false)
+------+-----+
|number|word |
+------+-----+
|8     |bat  |
|64    |mouse|
|-27   |horse|
+------+-----+


在跟踪 -3 中,我使用了 AND 操作,然后它删除了空/空值。

任何人都可以向我解释为什么 OR 操作不起作用? 我的代码有问题吗?

通常,Spark SQL(包括 SQL 和 DataFrame 和 Dataset API)不保证子表达式的计算顺序。 特别是,运算符或函数的输入不一定是从左到右或以任何其他固定顺序计算的。 例如,逻辑 AND 和 OR 表达式没有从左到右的“短路”语义。

因此,依赖于布尔表达式的副作用或求值顺序以及 WHERE 和 HAVING 子句的顺序是危险的,因为这些表达式和子句可以在查询优化和规划期间重新排序。 具体来说,如果 UDF 依赖 SQL 中的短路语义进行空检查,则不能保证在调用 UDF 之前会进行空检查。 例如,

现在让我们看看你的例子

路径 1: someDF.filter(col("word") =!= "" || col("word").isNotNull).show(false)

它是一个逻辑或运算符,意味着它足以让一侧为真:"" =!= "" -> false "".isnotNull -> true

意思是一个空词是真的,不应该被过滤掉

跟踪 2 和 3 与您使用的逻辑和运算符 "" =!= "" -> false 相同,这足以确定表达式为假并且应该被过滤掉。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM