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?

Ivan
la source
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.

zéro323
la source
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
31

Essayez d'utiliser simplement la fonction isNotNull .

df.filter(df.dt_mvmt.isNotNull()).count()
Anthony
la source
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")
Timctran
la source
2

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

df = df[df.dt_mvmt.isNotNull()]
Rae
la source
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'

user10238559
la source
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.

neeraj bhadani
la source
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
Swaminathan Meenakshisundaram
la source
0

J'essaierais aussi:

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

information_interchange
la source
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()
yogesh
la source
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

Rajashekar Reddy Peta
la source