PySpark mit Null und NA umgehen: Praktische Cleaning-Rezepte
Updated on
Null-Werte zerstören Metriken, Joins und Exporte, wenn sie unkontrolliert bleiben. Unbedachte dropna‑Aufrufe können außerdem wertvolle Zeilen entfernen. Teams brauchen klare Muster, um Nulls in PySpark gezielt zu inspizieren, zu füllen, zu droppen oder sicher zu vergleichen.
Die eingebauten Null-Handler von PySpark – fillna, dropna, na.replace, coalesce und null-sichere Vergleiche – machen Pipelines vorhersagbar und transparent.
Möchtest du schnell Data Visualization aus einem Python Pandas DataFrame ohne Code erstellen?
PyGWalker ist eine Python-Bibliothek für Exploratory Data Analysis mit Visualization. PyGWalker (opens in a new tab) kann deinen Jupyter-Notebook-Workflow für Data Analysis und Data Visualization vereinfachen, indem es deinen pandas DataFrame (und polars DataFrame) in eine tableau‑ähnliche Benutzeroberfläche für visuelle Exploration verwandelt.
Schnelle Entscheidungshilfe
| Ziel | API | Hinweise |
|---|---|---|
| Defaults auffüllen | fillna | Dict pro Spalte; Typen passend halten |
| Spärliche Zeilen droppen | dropna | how, thresh, subset steuern |
| Sentinel-Werte ersetzen | na.replace | Platzhalter-Strings oder -Zahlen austauschen |
| Ersten Nicht-Null-Wert wählen | coalesce | Spalten nach Priorität kombinieren |
| Null-sichere Gleichheit | <=> oder eqNullSafe | Behandelt Nulls als gleich |
Setup
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",
)Null-Muster inspizieren
null_stats = df.select(
*[
F.sum(F.col(c).isNull().cast("int")).alias(f"{c}_nulls")
for c in df.columns
]
)- Zähle Nulls pro Spalte, bevor du entscheidest, ob du füllst oder droppst.
Fehlende Werte auffüllen
filled = df.fillna({"name": "unknown", "tier": "basic", "score": 0})- Gib ein Dict an, um die Typen konsistent zu halten; vermeide es, numerische Spalten mit Strings zu füllen.
- Für Date/Timestamp-Spalten Domain-Defaults verwenden (
to_date('1970-01-01')).
Zeilen selektiv droppen
drop_sparse = df.dropna(thresh=3) # keep rows with >=3 non-null values
drop_missing_tier = df.dropna(subset=["tier"])threshschützt vor übermäßigem Droppen.- Bevorzuge Spalten-Subsets gegenüber pauschalem
dropna(), um nützliche Zeilen zu erhalten.
Sentinel-Werte ersetzen
clean_sent = df.na.replace({"N/A": None, "": None}, subset=["tier", "name"])- Konvertiere Platzhalter-Strings in echte Nulls, bevor du füllst oder droppst.
Mit Coalesce den ersten Nicht-Null wählen
with_fallback = df.withColumn("primary_tier", F.coalesce("tier", F.lit("basic")))coalescegibt das erste Nicht-Null-Argument zurück.
Null-sichere Vergleiche
matches = df.where(F.expr("tier <=> 'premium'"))<=>(odereqNullSafe) behandelt zwei Nulls als gleich; ein normales=liefert für Null-Vergleiche selbst Null.
Downstream-Joins absichern
- Fülle Join-Keys nur, wenn es fachlich erlaubt ist; ansonsten Null-Keys explizit filtern.
- Für Fact‑zu‑Dimension‑Joins entscheiden: Null-Keys vor dem Join droppen oder beibehalten und später behandeln.
Minimale Cleaning-Pipeline
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")))
)Diese Sequenz standardisiert Platzhalter, behält Pflichtfelder bei, füllt mit fachlichen Defaults auf und hinterlässt eine klare Fallback-Spalte für Reporting.
