PySpark Gérer Null et NA : Recettes pratiques de nettoyage
Updated on
Les valeurs null cassent les métriques, les jointures et les exports lorsqu’elles ne sont pas contrôlées. Des appels silencieux à dropna peuvent aussi supprimer des lignes précieuses. Les équipes ont besoin de schémas explicites pour inspecter, remplir, supprimer ou comparer en sécurité les nulls dans PySpark.
Les mécanismes intégrés de gestion des nulls de PySpark — fillna, dropna, na.replace, coalesce et les comparaisons null-safe — rendent les pipelines prévisibles et transparents.
Vous voulez créer rapidement des Data Visualization à partir d’un DataFrame Python Pandas sans coder ?
PyGWalker est une librairie Python pour l’Exploratory Data Analysis avec Visualisation. PyGWalker (opens in a new tab) peut simplifier votre workflow d’analyse et de visualisation de données dans Jupyter Notebook, en transformant votre pandas dataframe (et polars dataframe) en une interface utilisateur alternative à Tableau pour l’exploration visuelle.
Guide de décision rapide
| Objectif | API | Notes |
|---|---|---|
| Remplir avec des valeurs par défaut | fillna | Dictionnaire par colonne ; respecter les types |
| Supprimer les lignes clairsemées | dropna | Contrôler how, thresh, subset |
| Remplacer les sentinelles | na.replace | Remplacer les chaînes ou nombres de placeholder |
| Prendre le premier non-null | coalesce | Combiner les colonnes par priorité |
| Égalité null-safe | <=> ou eqNullSafe | Considère les nulls comme égaux |
Préparation
from pyspark.sql import SparkSession, functions as F
spark = SparkSession.builder.appName("null-handling").getOrCreate()
df = spark.createDataFrame(
[
(1, "Alice", None, None),
(2, "Bob", "basic", 0),
(3, None, "premium", None),
],
"id INT, name STRING, tier STRING, score INT",
)Inspecter les motifs de null
null_stats = df.select(
*[
F.sum(F.col(c).isNull().cast("int")).alias(f"{c}_nulls")
for c in df.columns
]
)- Comptez les nulls par colonne avant de décider de les remplir ou de les supprimer.
Remplir les valeurs manquantes
filled = df.fillna({"name": "unknown", "tier": "basic", "score": 0})- Fournissez un dictionnaire pour garder les types alignés ; évitez de remplir des numériques avec des chaînes.
- Pour les dates/timestamps, utilisez des valeurs par défaut métier (
to_date('1970-01-01')).
Supprimer des lignes de manière sélective
drop_sparse = df.dropna(thresh=3) # keep rows with >=3 non-null values
drop_missing_tier = df.dropna(subset=["tier"])threshprotège contre une suppression excessive.- Préférez les sous-ensembles de colonnes plutôt qu’un
dropna()global pour conserver des lignes utiles.
Remplacer les valeurs sentinelles
clean_sent = df.na.replace({"N/A": None, "": None}, subset=["tier", "name"])- Convertissez les chaînes de placeholder en vrais nulls avant de remplir ou de supprimer.
Utiliser coalesce pour prendre le premier non-null
with_fallback = df.withColumn("primary_tier", F.coalesce("tier", F.lit("basic")))coalescerenvoie le premier argument non-null dans la liste.
Comparaisons null-safe
matches = df.where(F.expr("tier <=> 'premium'"))<=>(oueqNullSafe) considère deux nulls comme égaux ; l’opérateur=classique renvoie null pour les comparaisons impliquant des nulls.
Protéger les jointures en aval
- Ne remplissez les clés de jointure que lorsque les règles métier le permettent ; sinon, filtrez explicitement les clés nulles.
- Pour les jointures fact-to-dimension, décidez : supprimer les clés nulles avant la jointure, ou les conserver et les traiter plus tard.
Pipeline de nettoyage minimal
clean = (
df
.na.replace({"N/A": None, "": None})
.dropna(subset=["name"]) # require a name
.fillna({"tier": "basic", "score": 0})
.withColumn("tier_clean", F.coalesce("tier", F.lit("basic")))
)Cette séquence standardise les placeholders, conserve les champs obligatoires, remplit avec des valeurs par défaut métier et laisse une colonne de repli claire pour le reporting.
