PySpark Select, Filter und withColumn: Zentrale DataFrame-Rezepte
Updated on
Unaufgeräumte DataFrames bremsen jede Pipeline: falsche Spalten, unsichere Filter und fragile Casts erzeugen stille Fehler. Teams brauchen wiederverwendbare Patterns für Auswahl, Filterung und abgeleitete Spalten, um Spark-Jobs vorhersehbar zu halten.
PySpark-APIs wie select, filter/where und withColumn lösen das, indem sie Transformationen explizit, typsicher und testbar machen. Dieser Guide zeigt die wichtigsten Patterns und wie man typische Stolperfallen vermeidet.
Du möchtest 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-alternative User Interface für visuelle Exploration verwandelt.
Leseweg
| Aufgabe | API | Wann verwenden |
|---|---|---|
| Spalten auswählen/umbenennen | select, alias | Nur benötigte Spalten behalten; selectExpr vermeiden, wenn es einfach ist |
| Zeilen filtern | filter / where | Beide identisch; Bedingungen mit & und | verketten |
| Abgeleitete/bedingte Spalten | withColumn, when/otherwise | Spalten mit Logik hinzufügen oder ersetzen |
| SQL-ähnliche Ausdrücke | selectExpr, expr | Schnelle Arithmetik oder SQL-Funktionen ohne viele Imports |
| Sicheres Casting | cast, try_cast (Spark 3.5+) | Typen erzwingen, ohne bei schlechten Werten zu werfen |
Setup und Beispieldaten
from pyspark.sql import SparkSession
from pyspark.sql import functions as F
spark = SparkSession.builder.appName("select-filter-withcolumn").getOrCreate()
df = spark.createDataFrame(
[
(1, "Alice", "2025-11-01", "premium", "42"),
(2, "Bob", "2025-11-02", "basic", "x"),
(3, "Cara", "2025-11-02", None, "7"),
],
"id INT, name STRING, signup_date STRING, tier STRING, score STRING",
)Wähle nur das, was du brauchst
slim = df.select(
"id",
F.col("name").alias("customer_name"),
F.to_date("signup_date").alias("signup_dt"),
)selecthält Projektionen explizit und vermeidet breite Scans.- Nutze
aliasfür lesbare Spaltennamen.
Filter / where: identische APIs
active = slim.where(
(F.col("signup_dt") >= "2025-11-01")
& (F.col("customer_name") != "Bob")
)filterundwheresind gleich; wähle eine Variante für Lesbarkeit.- Bedingungen mit
&und\|kombinieren; jede Bedingung in Klammern setzen. - Null-Checks:
isNull()/isNotNull()vermeiden Überraschungen.
withColumn für abgeleitete und bedingte Werte
scored = active.withColumn(
"score_int",
F.when(F.col("score").rlike("^[0-9]+$"), F.col("score").cast("int"))
.otherwise(None),
)withColumnfügt hinzu oder ersetzt; eindeutige Namen wählen, um versehentliches Überschreiben zu vermeiden.when/otherwiseformuliert Verzweigungslogik klar.
selectExpr für schnelle Ausdrücke
expr_df = df.selectExpr(
"id",
"upper(name) AS name_upper",
"to_date(signup_date) AS signup_dt",
"CASE WHEN tier = 'premium' THEN 1 ELSE 0 END AS is_premium",
)- Nützlich für SQL-artige Berechnungen ohne viele
functions-Imports. - Komplexe Logik besser in regulären
withColumn-Aufrufen halten für Lesbarkeit und Tests.
Muster für sicheres Casting
typed = (
df
.withColumn("score_int", F.col("score").cast("int"))
.withColumn("signup_ts", F.to_timestamp("signup_date"))
)- Explizite Casts bevorzugen; nicht auf Schema-Inferenz aus CSV-Quellen verlassen.
- Ab Spark 3.5+ gibt
try_castbei ungültigen Wertennullzurück, statt zu fehlschlagen.
Schnelle Checks für Datenqualität
from pyspark.sql import functions as F
bad_counts = df.select(
F.sum(F.col("score").rlike("^[0-9]+$").cast("int")).alias("valid_scores"),
F.sum(F.col("score").rlike("^[^0-9]").cast("int")).alias("invalid_scores"),
)- Vor dem Schreiben validieren; kleine Aggregationen decken Probleme früh auf.
- Mit
count+isNullFehlraten in Schlüsselspalten bestimmen.
Häufige Stolperfallen und Lösungen
- Nicht geklammerte Bedingungen: bei Nutzung von
&/\|jede boolesche Klausel einklammern. - Unabsichtliches Überschreiben von Spalten:
df.columnsprüfen oder mitwithColumnneue Namen nutzen. - String-Daten ohne Parsing: vor Vergleichen mit
to_date/to_timestampkonvertieren. - Null-sensitive Vergleiche: auf
isNull/isNotNullsetzen, um Überraschungen durch dreiwertige Logik zu vermeiden.
Minimales Pipeline-Beispiel
clean = (
df
.select("id", "name", "signup_date", "tier", "score")
.where(F.col("tier").isNotNull())
.withColumn("signup_dt", F.to_date("signup_date"))
.withColumn(
"score_int",
F.when(F.col("score").rlike("^[0-9]+$"), F.col("score").cast("int")),
)
)Damit bleiben Auswahl schlank, Filter explizit und abgeleitete Spalten typisiert, bevor sie in Downstream-Schritte geschrieben werden.
