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

时间:2017-08-31 09:34:49

标签: python apache-spark dataframe pyspark apache-spark-sql

有人可以向我解释为什么我会为这两个表达式得到不同的结果吗?我想在两个日期之间过滤:

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

结果:37M

VS

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

结果:25M

他们有什么不同?在我看来,他们应该产生相同的结果

2 个答案:

答案 0 :(得分:23)

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

~

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

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

在实践中,使用之间更有意义:

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

第一种方法甚至不是远程有效的。在Python中,df.filter(col("act_date").between("2016-10-01", "2017-04-01")) df.filter("act_date BETWEEN '2016-10-01' AND '2017-04-01'") 返回:

  • 如果所有表达式都是&#34; truthy&#34;。
  • ,则为最后一个元素
  • 第一个&#34; falsey&#34;否则。

结果

and

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

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

答案 1 :(得分:0)

在第一种情况下

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之间的值。