Фільтрувати стовпець кадру даних Pyspark зі значенням None


100

Я намагаюся відфільтрувати фрейм даних 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. Назва може ввести в оману.
Аторпат

У двох словах, порівняння, що включає null (або None, у цьому випадку) завжди повертає false. Зокрема, порівняння (null == null) повертає false. Крім того, порівняння (None == None) повертає false.
Річард Гомес,

Відповіді:


204

Ви можете використовувати 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/ isNotNullmethod.


2
Чудово, дякую. Я думав, що ці фільтри на фреймах даних PySpark будуть більш "пітонічними", але, на жаль, це не так. Я думаю про це запитати розробників.
Іван

1
Насправді це досить піфонічно. Ніколи не слід перевіряти __eq__з None;) І isне буде працювати, оскільки він поводиться не так.
zero323

2
Дивно, це працює лише для стовпців рядків ... Здається, це df.filter("dt_mvmt is not NULL")обробляє обидва.
Девід Аренбург,


14

Для отримання записів, значення яких у dt_mvmtстовпці не є нульовими, ми маємо

df.filter("dt_mvmt is not NULL")

а для записів, які є нульовими, ми маємо

df.filter("dt_mvmt is NULL")

2

Якщо ви хочете зберегти синтезатор Pandas, це спрацювало для мене.

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

1

якщо стовпець = Немає

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

Використовуйте створення спокусливого для фрейму даних:

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

Тому використовуйте: column_old_value='None'


1

Існує кілька способів видалити / відфільтрувати нульові значення зі стовпця в 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" у моєму блозі для отримання додаткової інформації.

Сподіваюся, це допоможе.


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 == Немає] .count () 0 df [df.dt_mvmt! = Немає] .count () 0

правильно

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.