Filtrar coluna de dataframe do Pyspark com valor Nenhum


98

Estou tentando filtrar um dataframe PySpark que tem Nonecomo valor de linha:

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

e posso filtrar corretamente com um valor de string:

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

mas isso falha:

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

Mas definitivamente existem valores em cada categoria. O que está acontecendo?


Na verdade, você deseja filtrar linhas com valores nulos, não uma coluna com valores Nenhum. O título pode ser enganoso.
Atorpat

Resumindo, uma comparação envolvendo nulo (ou Nenhum, neste caso) sempre retorna falso. Em particular, a comparação (null == null) retorna falso. Além disso, a comparação (Nenhum == Nenhum) retorna falso.
Richard Gomes

Respostas:


202

Você pode usar Column.isNull/ Column.isNotNull:

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

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

Se você deseja simplesmente descartar NULLvalores, pode usar na.dropcom o subsetargumento:

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

Comparações baseadas em igualdade com NULLnão funcionarão porque em SQL NULLé indefinido, portanto, qualquer tentativa de compará-lo com outro valor retorna NULL:

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


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

O único método válido para comparar o valor NULLé IS/ IS NOTque são equivalentes às chamadas de método isNull/ isNotNull.


2
Incrível, obrigado. Achei que esses filtros nos dataframes do PySpark seriam mais "pitônicos", mas não são. Estou pensando em perguntar aos desenvolvedores sobre isso.
Ivan

1
Na verdade, é bastante pitônico. Você nunca deve marcar __eq__com Nenhum;) E isnão funcionaria porque não se comporta da mesma maneira.
zero323

2
Estranhamente, isso só funciona para colunas de string ... Parece que df.filter("dt_mvmt is not NULL")lida com ambos.
David Arenburg de


14

Para obter entradas cujos valores na dt_mvmtcoluna não são nulos, temos

df.filter("dt_mvmt is not NULL")

e para entradas que são nulas, temos

df.filter("dt_mvmt is NULL")

2

Se você quiser manter o syntex do Pandas, isso funcionou para mim.

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

1

se coluna = Nenhum

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

Use create a tentable on data frame:

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

Então use: column_old_value='None'


1

Existem várias maneiras de remover / filtrar os valores nulos de uma coluna no DataFrame.

Vamos criar um DataFrame simples com o código abaixo:

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

Agora você pode tentar uma das abordagens abaixo para filtrar os valores nulos.

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

Você também pode verificar a seção "Trabalhando com valores NULL" no meu blog para obter mais informações.

Espero que ajude.


0

O PySpark oferece várias opções de filtragem com base em condições aritméticas, lógicas e outras. A presença de valores NULL pode dificultar outros processos. Removê-los ou imputá-los estatisticamente pode ser uma escolha.

O conjunto de código abaixo pode ser considerado:

# 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

Se você deseja filtrar os registros com valor Nenhum na coluna, veja o exemplo abaixo:

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

Agora filtre os registros de valor nulo:

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

df.show()

Se você deseja remover esses registros do DF, veja abaixo:

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

df1.show()

0

None / Null é um tipo de dados da classe NoneType em pyspark / python, portanto, a seguir não funcionará, pois você está tentando comparar o objeto NoneType com o objeto string

Forma errada de filreting

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

corrigir

df = df.where (col ("dt_mvmt"). isNotNull ()) retorna todos os registros com dt_mvmt como Nenhum / Nulo

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.