Pandas & NumPy Academy · Lektion

Metodkedjor med pipe()

Skriv lättlästa datapipelines med pipe() för att kedja anpassade funktioner med Pandas inbyggda metoder.

Lektion 4 av 413 steg

Metodkedjor med pipe() är en gratis lektion i Pandas & NumPy Academy på CoddyKit. Detta är lektion 4 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Pandas & NumPy Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Pandas & NumPy Academy innehåller totalt 4 lektioner.

Problemet med mellanliggande variabler

En datapipeline för rensning utan pipe() samlar ofta på sig många mellanliggande variabler: df1 = clean(df), df2 = transform(df1), df3 = enrich(df2). Dessa variabler belamrar namnrymden, gör felsökning svårare och frestar utvecklare att återanvända dem felaktigt. Resultatet blir kod som är svår att läsa uppifrån och ned som en sekvens av omvandlingar.

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)

Introduktion till pipe()

DataFrame.pipe(func) anropar func(df) och returnerar resultatet, vilket gör att Ni kan kedja anpassade funktioner på samma sätt som inbyggda Pandas-metoder som .dropna().query(). Den viktigaste fördelen är att varje omvandlingssteg är explicit och lättläst från vänster till höger, eller uppifrån och ned när koden formateras med parenteser, vilket speglar pipeline-logikens ordningsföljd.

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)

Skicka argument genom pipe()

Skicka extra argument till den funktion som anropas genom pipen med nyckelordsargument efter funktionsnamnet: df.pipe(func, arg1=val1). Funktionssignaturen måste ta emot df som sin första parameter. Parameteriserade funktioner gör pipelinen konfigurerbar: Ni kan ändra tröskelvärden, kolumnnamn eller beteende utan att ändra funktionskroppen, genom att bara ändra argumenten i pipe-anropet.

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)

Blanda pipe() med inbyggda metoder

Styrkan med pipe() är att den sömlöst integreras med inbyggda Pandas-metoder i samma kedja. Ni kan blanda .dropna(), .query(), .rename() och .pipe(custom_func) i valfri ordning. Det gör kedjan både kortfattad (genom att använda inbyggda metoder där det är möjligt) och flexibel (genom att använda anpassade funktioner där de inbyggda metoderna inte räcker till).

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())

Felsökning av en pipe()-kedja

Det kan vara svårt att felsöka en lång kedja eftersom Ni inte kan granska mellanliggande tillstånd genom att lägga in en utskrift mitt i kedjan. En lösning är att skriva en genomsläppande felsökningsfunktion som skriver ut information om form och kolumner och sedan returnerar DataFrame-objektet oförändrat. Infoga den på valfri plats i kedjan för att granska tillståndet vid det steget utan att bryta kedjan.

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')

Skapa en komplett pipeline för datarensning

Kombinera alla steg för datarensning i en enda pipeline-funktion med hjälp av pipe(). Genom att omsluta kedjan i en funktion som kallas clean_pipeline(df) blir pipelinen testbar som en enhet. Anropa den med ett rått DataFrame-objekt och få tillbaka ett rent. Detta mönster följer ETL-paradigmet (Extract, Transform, Load) som används inom data engineering i produktion.

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() jämfört med apply(): viktiga skillnader

pipe(func) skickar hela DataFrame-objektet till func och förväntar sig att få tillbaka ett DataFrame-objekt (eller ett transformerat objekt). apply(func, axis=1) skickar en rad i taget. Använd pipe() för transformationer av hela DataFrame-objektet som behåller samma form (eller avsiktligt ändrar den), och använd apply() för beräkningar på rad- eller kolumnnivå. De kompletterar varandra i stället för att konkurrera.

# 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')

Återanvändbara pipelinekomponenter

Skriv varje steg i pipelinen som en ren funktion — utan globalt tillstånd, med ett DataFrame-objekt som indata och ett DataFrame-objekt som returvärde. Rena funktioner är enkla att enhetstesta: anropa dem med ett litet test-DataFrame-objekt och verifiera utdataform och kolumnvärden. Ett bibliotek med testade, återanvändbara pipelinefunktioner snabbar upp analysen av nya dataset som har liknande krav på datarensning avsevärt.

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)

Logga pipelinesteg med pipe()

Lägg till strukturerad loggning i varje pipelinefunktion så att Ni kan granska varje transformation i produktion. Inkludera antal indata- och utdatarader samt relevant statistik (till exempel hur många rader som filtrerats bort). Då får Ni en fullständig spårning av varje pipelinekörning utan att behöva en extern arbetsflödesorkestrerare för grundläggande granskningsspår.

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.')

Villkorade steg i en pipeline

Ibland bör ett steg i datarensningen endast köras beroende på en flagga eller innehållet i datan. Ni kan lägga till villkorade steg i en pipe-kedja genom att infoga en identitets- eller transformationsfunktion: den kontrollerar ett villkor och tillämpar antingen en transformation eller returnerar DataFrame-objektet oförändrat. På så sätt behåller kedjan sin struktur samtidigt som valfria steg stöds.

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)

Exportera pipeline-resultatet

Det sista steget i en pipe()-kedja är ofta en export. Ni kan kedja en anpassad exportfunktion med hjälp av pipe() eller helt enkelt anropa Pandas inbyggda exportmetod efter kedjan. Genom att använda ett steg med pipe(save_to_parquet) blir exporten en del av kedjans dokumentation, och Ni säkerställer att den alltid körs på det slutliga rensade DataFrame-objektet, inte på en mellanversion.

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.')

Snabbtest

Testa Er förståelse av begreppen inom dataanalys från den här lektionen.

Sammanfattning av lektionen

I den här lektionen har Ni lärt Er: att använda pipe() för att kedja anpassade funktioner med Pandas inbyggda metoder, att skapa återanvändbara, parameteriserade och testbara pipelinesteg som rena funktioner samt att lägga till felsökningsloggning och villkorade steg i en pipe-kedja. Nästa steg är att utforska hur transformationssteg struktureras som funktioner för en ETL-pipeline i produktion.

Gratis att börja

Lär dig Python med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
30
Lektioner
120

Vanliga frågor

Är lektionen ”Metodkedjor med pipe()” gratis?

Ja – hela texten till ”Metodkedjor med pipe()” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Pandas & NumPy Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i Pandas & NumPy Academy innehåller totalt 4 lektioner.

Vad lär jag mig i ”Metodkedjor med pipe()”?

Skriv lättlästa datapipelines med pipe() för att kedja anpassade funktioner med Pandas inbyggda metoder. Ni övar på Pandas & NumPy Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig Pandas & NumPy Academy?

Du behöver inga förkunskaper. Utbildningen i Pandas & NumPy Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 4 av 4.

Hur lång tid tar lektionen ”Metodkedjor med pipe()”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här Pandas & NumPy Academy-lektionen?

Ja. Varje Pandas & NumPy Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. apply() på kolumner och rader
  2. apply() med GroupBy
  3. map() och applymap() för elementvisa operationer
  4. Metodkedjor med pipe()
← Tillbaka till Pandas & NumPy Academy