Filtruj kolumnę ramki danych Pyspark z wartością Brak

104

Próbuję filtrować ramkę danych PySpark, która ma Nonejako wartość wiersza:

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

i mogę poprawnie filtrować za pomocą wartości ciągu:

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

ale to się nie udaje:

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

Ale z pewnością są wartości w każdej kategorii. Co się dzieje?

Ivan
źródło
W rzeczywistości chcesz filtrować wiersze z wartościami null, a nie kolumną z wartościami None. Tytuł może wprowadzać w błąd.
Atorpat
Krótko mówiąc, porównanie obejmujące wartość null (lub w tym przypadku None) zawsze zwraca fałsz. W szczególności porównanie (null == null) zwraca fałsz. Również porównanie (None == None) zwraca false.
Richard Gomes

Odpowiedzi:

213

Możesz użyć Column.isNull/ Column.isNotNull:

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

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

Jeśli chcesz po prostu usunąć NULLwartości, których możesz użyć na.dropz subsetargumentem:

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

Porównania oparte na równości z NULLnie będą działać, ponieważ w SQL NULLjest niezdefiniowane, więc każda próba porównania z inną wartością zwraca NULL:

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


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

Jedyną prawidłową metodą porównywania wartości NULLjest IS/, IS NOTktóra jest równoważna wywołaniom metody isNull/ isNotNull.

zero323
źródło
2
Wielkie dzieki. Myślałem, że te filtry w ramkach danych PySpark będą bardziej „pythonowe”, ale niestety tak nie jest. Zastanawiam się, czy zapytać o to deweloperów.
Ivan
1
Właściwie jest całkiem Pythonic. Nigdy nie powinieneś sprawdzać __eq__z None;) I isnie zadziała, ponieważ nie zachowuje się tak samo.
zero323
2
O dziwo, działa to tylko dla kolumn typu string ... Wygląda na to, że df.filter("dt_mvmt is not NULL")obsługuje oba.
David Arenburg
32

Spróbuj po prostu użyć funkcji isNotNull .

df.filter(df.dt_mvmt.isNotNull()).count()
Anthony
źródło
15

Aby uzyskać wpisy, których wartości w dt_mvmtkolumnie nie są zerowe, mamy

df.filter("dt_mvmt is not NULL")

a dla wpisów, które są zerowe, mamy

df.filter("dt_mvmt is NULL")
timctran
źródło
2

Jeśli chcesz pozostać przy synteksie Pandas, zadziałało to dla mnie.

df = df[df.dt_mvmt.isNotNull()]
Rae
źródło
2

Istnieje wiele sposobów usuwania / filtrowania wartości null z kolumny w DataFrame.

Stwórzmy prostą ramkę DataFrame z poniższym kodem:

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

Teraz możesz wypróbować jedną z poniższych metod, aby odfiltrować wartości null.

# 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.

Możesz również sprawdzić sekcję „Praca z wartościami NULL” na moim blogu, aby uzyskać więcej informacji.

Mam nadzieję, że to pomoże.

neeraj bhadani
źródło
1

jeśli kolumna = Brak

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

Użyj stworzyć pokusę na ramce danych:

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

Więc użyj: column_old_value='None'

user10238559
źródło
0

PySpark zapewnia różne opcje filtrowania oparte na warunkach arytmetycznych, logicznych i innych. Obecność wartości NULL może utrudniać dalsze procesy. Usunięcie ich lub przypisanie im statystycznie może być wyborem.

Można rozważyć poniższy zestaw kodów:

# 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
Swaminathan Meenakshisundaram
źródło
0

Spróbowałbym też:

df = df.dropna(subset=["dt_mvmt"])

wymiana_informacyjna
źródło
0

Jeśli chcesz odfiltrować rekordy mające wartość Brak w kolumnie, zobacz poniższy przykład:

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

Teraz odfiltruj rekordy wartości null:

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

df.show()

Jeśli chcesz usunąć te rekordy z DF, zobacz poniżej:

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

df1.show()
jogesh
źródło
0

None / Null to typ danych klasy NoneType w pyspark / python, więc poniżej nie będzie działać, gdy próbujesz porównać obiekt NoneType z obiektem ciągu

Niewłaściwy sposób filtrowania

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

poprawny

df = df.where (col ("dt_mvmt"). isNotNull ()) zwraca wszystkie rekordy z wartością dt_mvmt jako None / Null

Rajashekar Reddy Peta
źródło