Method Chaining mit pipe()
Schreiben Sie lesbare Daten-Transformationspipelines, indem Sie mit pipe() benutzerdefinierte Funktionen zusammen mit nativen Pandas-Methoden verketten.
Method Chaining mit pipe() ist eine kostenlose Pandas & NumPy Academy-Lektion auf CoddyKit. Dies ist Lektion 4 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Pandas & NumPy Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Pandas & NumPy Academy-Kurs umfasst insgesamt 4 Lektionen.
Das Problem mit Zwischenvariablen
Eine Datenbereinigungspipeline ohne pipe() sammelt häufig viele Zwischenvariablen an: df1 = clean(df), df2 = transform(df1), df3 = enrich(df2). Diese Variablen überladen den Namensraum, erschweren das Debuggen und verleiten dazu, sie fälschlicherweise wiederzuverwenden. Das Ergebnis ist Code, der sich nur schwer von oben nach unten als Abfolge von Transformationen lesen lässt.
import pandas as pd
df = pd.read_csv('orders.csv')
# Without pipe — intermediate variables everywhere
df1 = df.dropna(subset=['revenue'])
df2 = df1[df1['quantity'] > 0]
df3 = df2.assign(revenue_per_unit=df2['revenue'] / df2['quantity'])
print(df3.shape)Einführung in pipe()
DataFrame.pipe(func) ruft func(df) auf und gibt das Ergebnis zurück. Dadurch können Sie benutzerdefinierte Funktionen ebenso verketten wie native Pandas-Methoden, etwa .dropna().query(). Der wichtigste Vorteil besteht darin, dass jeder Transformationsschritt explizit und von links nach rechts lesbar ist — beziehungsweise bei einer Formatierung mit Klammern von oben nach unten — und damit der logischen Reihenfolge der Pipeline entspricht.
def drop_nulls(df):
return df.dropna(subset=['revenue'])
def filter_positive_qty(df):
return df[df['quantity'] > 0]
def add_revenue_per_unit(df):
return df.assign(revenue_per_unit=df['revenue'] / df['quantity'])
# With pipe — clean chain
df_clean = (df
.pipe(drop_nulls)
.pipe(filter_positive_qty)
.pipe(add_revenue_per_unit)
)
print(df_clean.shape)Argumente durch pipe() übergeben
Übergeben Sie der durchgereichten Funktion zusätzliche Argumente, indem Sie nach dem Funktionsnamen Schlüsselwortargumente angeben: df.pipe(func, arg1=val1). Die Signatur der Funktion muss df als ersten Parameter akzeptieren. Parametrisierte Funktionen machen die Pipeline konfigurierbar: Sie können Schwellenwerte, Spaltennamen oder das Verhalten ändern, ohne den Funktionskörper anzupassen — ändern Sie einfach die Argumente des pipe-Aufrufs.
def filter_by_region(df, regions):
return df[df['region'].isin(regions)]
def cap_revenue(df, upper):
df = df.copy()
df['revenue'] = df['revenue'].clip(upper=upper)
return df
df_result = (df
.pipe(filter_by_region, regions=['North', 'East'])
.pipe(cap_revenue, upper=1000)
)
print(df_result.shape)pipe() mit nativen Methoden kombinieren
Die Stärke von pipe() liegt darin, dass es sich nahtlos in derselben Kette mit nativen Pandas-Methoden kombinieren lässt. Sie können .dropna(), .query(), .rename() und .pipe(custom_func) in beliebiger Reihenfolge mischen. Dadurch bleibt die Kette sowohl kompakt (weil nach Möglichkeit integrierte Methoden verwendet werden) als auch flexibel (weil Sie eigene Funktionen einsetzen können, wenn die integrierten Methoden nicht ausreichen).
df_result = (
df
.dropna(subset=['revenue', 'order_date'])
.query('quantity > 0')
.rename(columns={'unit_price': 'price'})
.pipe(add_revenue_per_unit)
.reset_index(drop=True)
)
print(df_result.head())Eine pipe()-Kette debuggen
Das Debuggen einer langen Kette kann schwierig sein, da Sie Zwischenzustände nicht einfach durch das Einfügen einer print-Anweisung in der Mitte untersuchen können. Eine Lösung besteht darin, eine Passthrough-Debug-Funktion zu schreiben, die Informationen zu Shape und Spalten ausgibt und anschließend den DataFrame unverändert zurückgibt. Fügen Sie sie an beliebiger Stelle in die Kette ein, um den Zustand an diesem Schritt zu untersuchen, ohne die Kette zu unterbrechen.
def debug(df, label=''):
print(f'[{label}] shape: {df.shape}')
print(f'[{label}] columns: {df.columns.tolist()}')
return df
df_result = (
df
.pipe(drop_nulls)
.pipe(debug, label='after drop_nulls')
.pipe(filter_positive_qty)
.pipe(debug, label='after filter')
)
print('Done')Eine vollständige Cleaning-Pipeline erstellen
Fassen Sie alle Bereinigungsschritte mithilfe von pipe() in einer einzigen Pipeline-Funktion zusammen. Wenn Sie die Kette in eine Funktion namens clean_pipeline(df) einschließen, lässt sich die Pipeline als Einheit testen. Rufen Sie sie mit einem rohen DataFrame auf und erhalten Sie einen bereinigten zurück. Dieses Muster entspricht dem in der Data-Engineering-Praxis verwendeten ETL-Paradigma (Extract, Transform, Load).
def clean_pipeline(df):
return (
df
.dropna(subset=['order_id', 'revenue'])
.drop_duplicates(subset=['order_id'])
.query('quantity > 0 and revenue >= 0')
.pipe(add_revenue_per_unit)
.reset_index(drop=True)
)
df_clean = clean_pipeline(df)
print('Clean rows:', len(df_clean))pipe() vs. apply(): Die wichtigsten Unterschiede
pipe(func) übergibt den gesamten DataFrame an func und erwartet als Rückgabe einen DataFrame (oder ein transformiertes Objekt). apply(func, axis=1) übergibt jeweils eine Zeile. Verwenden Sie pipe() für Transformationen des gesamten DataFrames, die dieselbe Form beibehalten (oder sie bewusst ändern), und apply() für Berechnungen auf Zeilen- oder Spaltenebene. Die beiden Methoden ergänzen sich und stehen nicht in Konkurrenz zueinander.
# pipe: receives the whole DataFrame
def scale_revenue(df, factor=1.0):
df = df.copy()
df['revenue'] = df['revenue'] * factor
return df
# apply: receives one row at a time
df['revenue_x2'] = df.apply(lambda row: row['revenue'] * 2, axis=1)
df_scaled = df.pipe(scale_revenue, factor=1.1)
print('pipe scales all rows at once; apply does row-by-row')Wiederverwendbare Pipeline-Komponenten
Schreiben Sie jeden Pipelineschritt als pure Funktion – ohne globalen Zustand, mit einem DataFrame als Eingabe und einem DataFrame als Rückgabe. Pure Funktionen lassen sich leicht als Unit testen: Rufen Sie sie mit einem kleinen Test-DataFrame auf und prüfen Sie Shape sowie Spaltenwerte der Ausgabe. Eine Bibliothek getesteter, wiederverwendbarer Pipeline-Funktionen beschleunigt die Analyse neuer Datensätze mit ähnlichen Bereinigungsanforderungen erheblich.
def normalise_strings(df, cols):
df = df.copy()
for col in cols:
df[col] = df[col].str.strip().str.lower()
return df
def parse_dates(df, cols):
df = df.copy()
for col in cols:
df[col] = pd.to_datetime(df[col])
return df
df_result = (
df
.pipe(normalise_strings, cols=['region', 'category'])
.pipe(parse_dates, cols=['order_date'])
)
print(df_result.dtypes)Pipelineschritte mit pipe() protokollieren
Fügen Sie in jede Pipeline-Funktion strukturierte Protokollierung ein, damit Sie in der Produktion jede Transformation nachvollziehen können. Erfassen Sie die Anzahl der Eingabe- und Ausgabezeilen sowie relevante Statistiken (z. B. die Anzahl der durch einen Filter entfernten Zeilen). So erhalten Sie eine vollständige Nachverfolgung jedes Pipelinelaufs, ohne für grundlegende Audit-Trails einen externen Workflow-Orchestrator zu benötigen.
import logging
logging.basicConfig(level=logging.INFO)
def logged_dropna(df, subset):
before = len(df)
df = df.dropna(subset=subset)
after = len(df)
logging.info(f'dropna: {before - after} rows removed, {after} remaining')
return df
df_clean = df.pipe(logged_dropna, subset=['revenue'])
print('Logged pipeline complete.')Bedingte Schritte in einer Pipeline
Manchmal soll ein Bereinigungsschritt nur abhängig von einem Flag oder vom Inhalt der Daten ausgeführt werden. Sie können bedingte Schritte in eine pipe-Kette einfügen, indem Sie eine Identitäts- oder Transformationsfunktion verwenden: Sie prüft eine Bedingung und wendet entweder eine Transformation an oder gibt den DataFrame unverändert zurück. So bleibt die Struktur der Kette erhalten, während optionale Schritte unterstützt werden.
def maybe_cap_revenue(df, cap=None):
if cap is None:
return df
df = df.copy()
df['revenue'] = df['revenue'].clip(upper=cap)
return df
CAPPING_ENABLED = True
CAP_VALUE = 1000 if CAPPING_ENABLED else None
df_result = df.pipe(maybe_cap_revenue, cap=CAP_VALUE)
print('Conditional step applied:', CAPPING_ENABLED)Das Pipeline-Ergebnis exportieren
Der letzte Schritt einer pipe()-Kette ist häufig ein Export. Sie können mit pipe() eine eigene Exportfunktion an die Kette anhängen oder nach der Kette einfach die native Pandas-Exportmethode aufrufen. Mit einem Schritt wie pipe(save_to_parquet) bleibt der Export Bestandteil der Kettendokumentation und wird garantiert immer auf dem zuletzt bereinigten DataFrame ausgeführt, nicht auf einer Zwischenversion.
def save_parquet(df, path):
df.to_parquet(path, index=False)
print(f'Saved {len(df)} rows to {path}')
return df # return df so the chain can continue if needed
df_final = (
df
.pipe(clean_pipeline)
.pipe(save_parquet, path='orders_final.parquet')
)
print('Pipeline complete.')Kurzübung
Testen Sie Ihr Verständnis der Konzepte der Datenanalyse aus dieser Lektion.
Zusammenfassung der Lektion
In dieser Lektion haben Sie gelernt: mit pipe() eigene Funktionen und native Pandas-Methoden zu verketten, wiederverwendbare, parametrisierte und testbare Pipelineschritte als pure Funktionen zu erstellen und Debug-Protokollierung sowie bedingte Schritte in eine pipe-Kette einzufügen. Als Nächstes untersuchen wir, wie sich Transformationsschritte als Funktionen für eine produktive ETL-Pipeline strukturieren lassen.
Häufig gestellte Fragen
Ist die Lektion „Method Chaining mit pipe()“ kostenlos?
Ja — der vollständige Text von „Method Chaining mit pipe()“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Pandas & NumPy Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Pandas & NumPy Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Method Chaining mit pipe()“?
Schreiben Sie lesbare Daten-Transformationspipelines, indem Sie mit pipe() benutzerdefinierte Funktionen zusammen mit nativen Pandas-Methoden verketten. Du übst Pandas & NumPy Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um Pandas & NumPy Academy zu starten?
Keine Vorkenntnisse erforderlich. Pandas & NumPy Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 4 von 4.
Wie lange dauert die Lektion „Method Chaining mit pipe()“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser Pandas & NumPy Academy-Lektion Code schreiben und ausführen?
Ja. Jede Pandas & NumPy Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- apply() auf Spalten und Zeilen
- apply() mit GroupBy
- map() und applymap() für elementweise Operationen
- Method Chaining mit pipe()