Skip to content

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.

PyGWalker for Data visualization (opens in a new tab)

Guide de décision rapide

ObjectifAPINotes
Remplir avec des valeurs par défautfillnaDictionnaire par colonne ; respecter les types
Supprimer les lignes clairseméesdropnaContrôler how, thresh, subset
Remplacer les sentinellesna.replaceRemplacer les chaînes ou nombres de placeholder
Prendre le premier non-nullcoalesceCombiner les colonnes par priorité
Égalité null-safe<=> ou eqNullSafeConsidè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"])
  • thresh protè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")))
  • coalesce renvoie le premier argument non-null dans la liste.

Comparaisons null-safe

matches = df.where(F.expr("tier <=> 'premium'"))
  • <=> (ou eqNullSafe) 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.