Filtrer la colonne de dataframe Pyspark avec la valeur Aucun


100

J'essaie de filtrer un dataframe PySpark qui a Nonecomme valeur de ligne:

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

et je peux filtrer correctement avec une valeur de chaîne:

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

mais cela échoue:

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

Mais il y a certainement des valeurs dans chaque catégorie. Que se passe-t-il?


Vous souhaitez en fait filtrer les lignes avec des valeurs nulles, pas une colonne avec des valeurs Aucune. Le titre pourrait être trompeur.
Atorpat

En un mot, une comparaison impliquant null (ou None, dans ce cas) renvoie toujours false. En particulier, la comparaison (null == null) renvoie false. De plus, la comparaison (None == None) renvoie false.
Richard Gomes

Réponses:


204

Vous pouvez utiliser Column.isNull/ Column.isNotNull:

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

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

Si vous souhaitez simplement supprimer les NULLvaleurs que vous pouvez utiliser na.dropavec l' subsetargument:

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

Les comparaisons basées sur l'égalité avec NULLne fonctionneront pas car dans SQL NULLn'est pas défini, toute tentative de comparaison avec une autre valeur renvoie NULL:

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


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

La seule méthode valide avec laquelle comparer la valeur NULLest IS/ IS NOTqui sont équivalents aux appels de méthode isNull/ isNotNull.


2
Super merci. Je pensais que ces filtres sur les dataframes PySpark seraient plus "pythoniques", mais hélas, ils ne le sont pas. Je pense interroger les développeurs à ce sujet.
Ivan

1
En fait, c'est assez pythonique. Vous ne devriez jamais vérifier __eq__avec None;) Et isne fonctionnerait pas car il ne se comporte pas de la même manière.
zero323

2
Étrangement, cela ne fonctionne que pour les colonnes de chaînes ... Il semble que cela df.filter("dt_mvmt is not NULL")gère les deux.
David Arenburg


14

Pour obtenir des entrées dont les valeurs dans la dt_mvmtcolonne ne sont pas nulles nous avons

df.filter("dt_mvmt is not NULL")

et pour les entrées nulles, nous avons

df.filter("dt_mvmt is NULL")

2

Si vous voulez rester avec le syntex Pandas, cela a fonctionné pour moi.

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

1

si colonne = Aucun

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

Utilisez créer un tentable sur un bloc de données:

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

Alors utilisez: column_old_value='None'


1

Il existe plusieurs façons de supprimer / filtrer les valeurs nulles d'une colonne dans DataFrame.

Permet de créer un DataFrame simple avec le code ci-dessous:

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

Vous pouvez maintenant essayer l'une des approches ci-dessous pour filtrer les valeurs nulles.

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

Vous pouvez également consulter la section "Travailler avec des valeurs NULL" sur mon blog pour plus d'informations.

J'espère que cela aide.


0

PySpark fournit diverses options de filtrage basées sur des conditions arithmétiques, logiques et autres. La présence de valeurs NULL peut gêner d'autres processus. Les supprimer ou les imputer statistiquement pourrait être un choix.

L'ensemble de code ci-dessous peut être considéré:

# 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

Si vous souhaitez filtrer les enregistrements ayant une valeur Aucune dans la colonne, consultez l'exemple ci-dessous:

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

Filtrez maintenant les enregistrements de valeur nulle:

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

df.show()

Si vous souhaitez supprimer ces enregistrements de DF, voir ci-dessous:

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

df1.show()

0

None / Null est un type de données de la classe NoneType dans pyspark / python donc, ci-dessous ne fonctionnera pas car vous essayez de comparer l'objet NoneType avec l'objet string

Mauvaise façon de filtrer

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

correct

df = df.where (col ("dt_mvmt"). isNotNull ()) renvoie tous les enregistrements avec dt_mvmt comme None / Null

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.