Отфильтровать столбец данных Pyspark без значения None

23

Я пытаюсь отфильтровать фрейм данных PySpark с None в качестве значения строки:

df.select('dt_mvmt').distinct().collect()

[Row(dt_mvmt=u'2016-03-27'),
 Row(dt_mvmt=u'2016-03-28'),
 Row(dt_mvmt=u'2016-03-29'),
 Row(dt_mvmt=None),
 Row(dt_mvmt=u'2016-03-30'),
 Row(dt_mvmt=u'2016-03-31')]

, и я могу правильно фильтровать со строковым значением:

df[df.dt_mvmt == '2016-03-31']
# some results here

, но это не удается:

df[df.dt_mvmt == None].count()
0
df[df.dt_mvmt != None].count()
0

Но в каждой категории есть определенные значения. Что происходит?

    
задан Ivan 16.05.2016 в 22:31
источник
  • Согласно PEP 8, вы должны использовать is и не для сравнения с синглонами типа None. –  Natecat 16.05.2016 в 22:36
  • Да, но нет фильтра или нет для фильтрации фреймов данных PySpark: В [222]: df [df.dt_mvmt is None] .show () TypeError: объект «Column» не может быть вызван –  Ivan 16.05.2016 в 22:40

3 ответа

52

Вы можете использовать Column.isNull / Column.isNotNull :

df.where(col("dt_mvmt").isNull())

df.where(col("dt_mvmt").isNotNull())

Если вы хотите просто отказаться от значений NULL , вы можете использовать na.drop с аргументом subset :

df.na.drop(subset=["dt_mvmt"])

Сравнение на основе равенства с NULL не будет работать, потому что в SQL NULL не определено, поэтому любая попытка сравнить его с другим значением возвращает NULL :

sqlContext.sql("SELECT NULL = NULL").show()
## +-------------+
## |(NULL = NULL)|
## +-------------+
## |         null|
## +-------------+


sqlContext.sql("SELECT NULL != NULL").show()
## +-------------------+
## |(NOT (NULL = NULL))|
## +-------------------+
## |               null|
## +-------------------+

Единственным допустимым методом сравнения значения с NULL является IS / IS NOT , которые эквивалентны вызовам isNull / isNotNull .     

ответ дан zero323 16.05.2016 в 22:45
источник
  • Удивительно, спасибо. Я думал, что эти фильтры на фреймах PySpark будут более «питоновскими», но, увы, это не так. Я думаю о том, чтобы спросить разработчиков об этом. –  Ivan 17.05.2016 в 14:25
  • На самом деле это довольно Pythonic. Вы никогда не должны проверять __eq__ с None;) И не будет работать, потому что он не ведет себя одинаково. –  zero323 17.05.2016 в 14:37
  • Странно это работает только для строковых столбцов ... Похоже, df.filter («dt_mvmt is not NULL») обрабатывает оба. –  David Arenburg 20.08.2017 в 11:14
11

Попробуйте использовать функцию isNotNull .

df.filter(df.dt_mvmt.isNotNull()).count()
    
ответ дан Anthony 16.05.2016 в 22:50
источник
  • ты качаешь !!!!!!! –  logan 26.01.2018 в 03:24
5

Чтобы получить записи, значения которых в столбце dt_mvmt не равны нулю, мы имеем

df.filter("dt_mvmt is not NULL")

, а для нулевых записей имеем

df.filter("dt_mvmt is NULL")
    
ответ дан timctran 09.02.2017 в 03:37
источник