数据框上的多个条件过滤器

Posted

技术标签:

【中文标题】数据框上的多个条件过滤器【英文标题】:Multiple condition filter on dataframe 【发布时间】:2018-02-09 05:05:59 【问题描述】:

任何人都可以向我解释为什么这两个表达式得到不同的结果吗?我正在尝试在 2 个日期之间进行过滤:

df.filter("act_date <='2017-04-01'" and "act_date >='2016-10-01'")\
  .select("col1","col2").distinct().count()

结果:37M

df.filter("act_date <='2017-04-01'").filter("act_date >='2016-10-01'")\
  .select("col1","col2").distinct().count()

结果:25M

它们有何不同?在我看来,它们应该产生相同的结果

【问题讨论】:

【参考方案1】:

TL;DR 要将多个条件传递给filterwhere,请使用Column 对象和逻辑运算符(&amp;|~)。见Pyspark: multiple conditions in when clause。

df.filter((col("act_date") >= "2016-10-01") & (col("act_date") <= "2017-04-01"))

您也可以使用单个 SQL 字符串:

df.filter("act_date >='2016-10-01' AND act_date <='2017-04-01'")

在实践中使用 between 更有意义:

df.filter(col("act_date").between("2016-10-01", "2017-04-01"))
df.filter("act_date BETWEEN '2016-10-01' AND '2017-04-01'")

第一种方法甚至不是远程有效的。在 Python 中,and 返回:

如果所有表达式都是“真实的”,则为最后一个元素。 否则是第一个“falsey”元素。

结果

"act_date <='2017-04-01'" and "act_date >='2016-10-01'"

被评估为(任何非空字符串都是真实的):

"act_date >='2016-10-01'"

【讨论】:

【参考方案2】:

第一种情况

df.filter("act_date <='2017-04-01'" and "act_date >='2016-10-01'")\
  .select("col1","col2").distinct().count()

结果是超过 2016-10-01 的值,这意味着所有高于 2017-04-01 的值。

而在第二种情况下

df.filter("act_date <='2017-04-01'").filter("act_date >='2016-10-01'")\
  .select("col1","col2").distinct().count()

结果是 2016-10-01 到 2017-04-01 之间的值。

【讨论】:

向过滤器添加多个条件时出现此错误 Py4JError: An error occurred while calling o355.or. Trace: py4j.Py4JException: Method or([class java.lang.String]) 不存在

以上是关于数据框上的多个条件过滤器的主要内容,如果未能解决你的问题,请参考以下文章

针对ramda中的过滤器上的多个条件进行测试

多个条件的过滤列表

如何在过滤数据表jQuery中制作多个条件

Pyspark:根据多个条件过滤数据帧

使用具有多个搜索条件的 Knex.js 和 SQL 的条件过滤器

在 dplyr 中按组过滤多个条件的条件 IF