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


105

Я пытаюсь отфильтровать фрейм данных 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

Но в каждой категории определенно есть свои ценности. В чем дело?


На самом деле вы хотите фильтровать строки с нулевыми значениями, а не столбец со значениями None. Название может вводить в заблуждение.
Atorpat 07

Короче говоря, сравнение с использованием null (или None в данном случае) всегда возвращает false. В частности, сравнение (null == null) возвращает false. Кроме того, сравнение (None == None) возвращает false.
Ричард Гомес

Ответы:


218

Вы можете использовать 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метода.


2
Отлично, спасибо. Я думал, что эти фильтры на фреймах данных PySpark будут более «питоническими», но, увы, это не так. Думаю спросить об этом у разработчиков.
Иван

1
На самом деле это довольно Pythonic. Вы никогда не должны проверять __eq__с помощью None;) И isне будет работать, потому что он ведет себя иначе.
zero323

2
Как ни странно, это работает только для строковых столбцов ... Кажется, работает и то, и df.filter("dt_mvmt is not NULL")другое.
Дэвид Аренбург


15

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

df.filter("dt_mvmt is not NULL")

и для записей, которые являются нулевыми, мы имеем

df.filter("dt_mvmt is NULL")

2

Если вы хотите сохранить синтекс Pandas, это сработало для меня.

df = df[df.dt_mvmt.isNotNull()]

2

Есть несколько способов удалить / отфильтровать нулевые значения из столбца в DataFrame.

Давайте создадим простой DataFrame с приведенным ниже кодом:

date = ['2016-03-27','2016-03-28','2016-03-29', None, '2016-03-30','2016-03-31']
df = spark.createDataFrame(date, StringType())

Теперь вы можете попробовать один из следующих подходов для фильтрации нулевых значений.

# Approach - 1
df.filter("value is not null").show()

# Approach - 2
df.filter(col("value").isNotNull()).show()

# Approach - 3
df.filter(df["value"].isNotNull()).show()

# Approach - 4
df.filter(df.value.isNotNull()).show()

# Approach - 5
df.na.drop(subset=["value"]).show()

# Approach - 6
df.dropna(subset=["value"]).show()

# Note: You can also use where function instead of a filter.

Вы также можете проверить раздел «Работа со значениями NULL» в моем блоге для получения дополнительной информации.

Я надеюсь, что это помогает.


1

если столбец = Нет

COLUMN_OLD_VALUE
----------------
None
1
None
100
20
------------------

Используйте create a temptable во фрейме данных:

sqlContext.sql("select * from tempTable where column_old_value='None' ").show()

Так что используйте: column_old_value='None'


0

PySpark предоставляет различные варианты фильтрации на основе арифметических, логических и других условий. Наличие значений NULL может помешать дальнейшим процессам. Можно было бы удалить их или статистически вменять.

Ниже представлен набор кода:

# Dataset is df
# Column name is dt_mvmt
# Before filtering make sure you have the right count of the dataset
df.count() # Some number

# Filter here
df = df.filter(df.dt_mvmt.isNotNull())

# Check the count to ensure there are NULL values present (This is important when dealing with large dataset)
df.count() # Count should be reduced if NULL values are present


0

Если вы хотите отфильтровать записи со значением None в столбце, см. Пример ниже:

df=spark.createDataFrame([[123,"abc"],[234,"fre"],[345,None]],["a","b"])

Теперь отфильтруйте записи с нулевым значением:

df=df.filter(df.b.isNotNull())

df.show()

Если вы хотите удалить эти записи из DF, см. Ниже:

df1=df.na.drop(subset=['b'])

df1.show()

0

None / Null - это тип данных класса NoneType в pyspark / python, поэтому ниже не будет работать, поскольку вы пытаетесь сравнить объект NoneType со строковым объектом

Неправильный способ фильтрования

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

верный

df = df.where (col ("dt_mvmt"). isNotNull ()) возвращает все записи с dt_mvmt как None / Null

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.