it-roy-ru.com

Фильтр нескольких условий на фрейме данных

Может кто-нибудь объяснить мне, почему я получаю разные результаты для этих двух выражений? Я пытаюсь отфильтровать 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

Насколько они разные ? Мне кажется, что они должны дать тот же результат

10
femibyte

TL; DR Для передачи нескольких условий в filter или where используйте Column объекты и логические операторы (&, |, ~). Смотрите Pyspark: несколько условий в условии когда .

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'")

На практике имеет смысл использовать между:

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 возвращает:

  • Последний элемент, если все выражения являются «правдивыми».
  • Первый «фальшивый» элемент в противном случае.

В следствии

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

оценивается как (любая непустая строка является достоверной):

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

В первом случае

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.

0
Ash Man