J'essaie d'obtenir toutes les lignes dans une trame de données où deux drapeaux sont définis sur "1" et par la suite tous ceux où un seul des deux est défini sur "1" et l'autre PAS ÉGAL à "1 "
Avec le schéma suivant (trois colonnes),
df = sqlContext.createDataFrame([('a',1,'null'),('b',1,1),('c',1,'null'),('d','null',1),('e',1,1)], #,('f',1,'NaN'),('g','bla',1)],
schema=('id', 'foo', 'bar')
)
J'obtiens le dataframe suivant:
+---+----+----+
| id| foo| bar|
+---+----+----+
| a| 1|null|
| b| 1| 1|
| c| 1|null|
| d|null| 1|
| e| 1| 1|
+---+----+----+
Lorsque j'applique les filtres souhaités, le premier filtre (foo = 1 AND bar = 1) fonctionne, mais pas l'autre (foo = 1 AND NOT bar = 1)
foobar_df = df.filter( (df.foo==1) & (df.bar==1) )
rendements:
+---+---+---+
| id|foo|bar|
+---+---+---+
| b| 1| 1|
| e| 1| 1|
+---+---+---+
Voici le filtre sans comportement:
foo_df = df.filter( (df.foo==1) & (df.bar!=1) )
foo_df.show()
+---+---+---+
| id|foo|bar|
+---+---+---+
+---+---+---+
Pourquoi ne filtre-t-il pas? Comment puis-je obtenir les colonnes où seul foo est égal à "1"?
Pour filtrer les valeurs nulles, essayez:
foo_df = df.filter( (df.foo==1) & (df.bar.isNull()) )
https://spark.Apache.org/docs/1.6.2/api/python/pyspark.sql.html#pyspark.sql.Column.isNull
Pourquoi ne filtre-t-il pas
Parce que c'est SQL et NULL
indique des valeurs manquantes. Pour cette raison, toute comparaison avec NULL
, autre que IS NULL
et IS NOT NULL
n'est pas défini. Vous avez besoin soit:
col("bar").isNull() | (col("bar") != 1)
ou
coalesce(col("bar") != 1, lit(True))
ou ( PySpark> = 2. ):
col("bar").eqNullSafe(1)
si vous voulez des comparaisons sûres nulles dans PySpark.
Également 'null'
n'est pas un moyen valide pour introduire NULL
littéral. Vous devez utiliser None
pour indiquer les objets manquants.
from pyspark.sql.functions import col, coalesce, lit
df = spark.createDataFrame([
('a', 1, 1), ('a',1, None), ('b', 1, 1),
('c' ,1, None), ('d', None, 1),('e', 1, 1)
]).toDF('id', 'foo', 'bar')
df.where((col("foo") == 1) & (col("bar").isNull() | (col("bar") != 1))).show()
## +---+---+----+
## | id|foo| bar|
## +---+---+----+
## | a| 1|null|
## | c| 1|null|
## +---+---+----+
df.where((col("foo") == 1) & coalesce(col("bar") != 1, lit(True))).show()
## +---+---+----+
## | id|foo| bar|
## +---+---+----+
## | a| 1|null|
## | c| 1|null|
## +---+---+----+