Pandas & NumPy Academy · Leçon

Chaînage de méthodes avec pipe()

Écrivez des pipelines de transformation de données lisibles avec pipe() pour enchaîner des fonctions personnalisées et les méthodes natives de Pandas.

Leçon 4 sur 413 étapes

Chaînage de méthodes avec pipe() est une leçon Pandas & NumPy Academy gratuite sur CoddyKit. Ceci est la leçon 4 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Pandas & NumPy Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Pandas & NumPy Academy comprend 4 leçons au total.

Le problème des variables intermédiaires

Un pipeline de nettoyage des données sans pipe() accumule souvent de nombreuses variables intermédiaires : df1 = clean(df), df2 = transform(df1), df3 = enrich(df2). Ces variables encombrent l'espace de noms, compliquent le débogage et incitent les développeurs à les réutiliser de manière incorrecte. Le code obtenu est difficile à lire de haut en bas comme une suite de transformations.

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)

Présentation de pipe()

DataFrame.pipe(func) appelle func(df) et renvoie le résultat, ce qui vous permet d'enchaîner des fonctions personnalisées de la même manière que les méthodes natives de Pandas, comme .dropna().query(). Le principal avantage est que chaque étape de transformation est explicite et lisible de gauche à droite, ou de haut en bas lorsqu'elle est mise en forme avec des parenthèses, en suivant l'ordre logique du pipeline.

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)

Transmettre des arguments avec pipe()

Transmettez des arguments supplémentaires à la fonction appelée par le pipeline à l'aide d'arguments nommés placés après le nom de la fonction : df.pipe(func, arg1=val1). La signature de la fonction doit accepter df comme premier paramètre. Les fonctions paramétrées rendent le pipeline configurable : vous pouvez modifier les seuils, les noms de colonnes ou le comportement sans modifier le corps de la fonction, simplement en changeant les arguments de l'appel à pipe.

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)

Combiner pipe() avec les méthodes natives

La puissance de pipe() tient au fait qu’il s’intègre parfaitement aux méthodes natives de Pandas dans la même chaîne. Vous pouvez combiner .dropna(), .query(), .rename() et .pipe(custom_func) dans n’importe quel ordre. La chaîne est ainsi à la fois concise (en utilisant les méthodes intégrées lorsque c’est possible) et flexible (en recourant à des fonctions personnalisées lorsque les méthodes intégrées ne suffisent pas).

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

Déboguer une chaîne avec pipe()

Déboguer une longue chaîne peut être délicat, car vous ne pouvez pas inspecter les états intermédiaires en ajoutant une instruction d’affichage au milieu. Une solution consiste à écrire une fonction de débogage transparente qui affiche les informations sur les dimensions et les colonnes, puis renvoie le DataFrame sans le modifier. Insérez-la à n’importe quel endroit de la chaîne pour examiner l’état à cette étape sans interrompre la chaîne.

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

Construire une chaîne de traitement complète

Combinez toutes les étapes de nettoyage dans une seule fonction de chaîne de traitement à l’aide de pipe(). Encapsuler la chaîne dans une fonction appelée clean_pipeline(df) rend la chaîne de traitement testable comme une unité. Appelez-la avec un DataFrame brut pour obtenir un DataFrame propre. Ce modèle s’inscrit dans le paradigme ETL (Extract, Transform, Load) utilisé en ingénierie des données en production.

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() ou apply() : principales différences

pipe(func) transmet l’intégralité du DataFrame à func et attend en retour un DataFrame (ou un objet transformé). apply(func, axis=1) transmet une ligne à la fois. Utilisez pipe() pour les transformations portant sur l’ensemble du DataFrame et conservant la même forme (ou la modifiant délibérément), et apply() pour les calculs au niveau des lignes ou des colonnes. Ces fonctions sont complémentaires, et non concurrentes.

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

Composants réutilisables d’une chaîne de traitement

Écrivez chaque étape de la chaîne de traitement sous forme de fonction pure — sans état global, recevant un DataFrame et renvoyant un DataFrame. Les fonctions pures sont faciles à tester unitairement : appelez-les avec un petit DataFrame de test et vérifiez la forme du résultat ainsi que les valeurs des colonnes. Une bibliothèque de fonctions de chaîne de traitement testées et réutilisables accélère considérablement l’analyse de nouveaux jeux de données ayant des besoins de nettoyage similaires.

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)

Journaliser les étapes avec pipe()

Ajoutez une journalisation structurée dans chaque fonction de la chaîne de traitement afin de pouvoir auditer chaque transformation en production. Incluez le nombre de lignes en entrée, le nombre de lignes en sortie et toutes les statistiques pertinentes (par exemple, le nombre de lignes supprimées par un filtre). Vous disposez ainsi d’une trace complète de chaque exécution de la chaîne de traitement, sans avoir besoin d’un orchestrateur de flux de travail externe pour les pistes d’audit de base.

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

Étapes conditionnelles dans une chaîne de traitement

Parfois, une étape de nettoyage ne doit être exécutée qu’en fonction d’un indicateur ou du contenu des données. Vous pouvez ajouter des étapes conditionnelles à une chaîne pipe en insérant une fonction qui conserve les données ou les transforme : elle vérifie une condition, puis applique une transformation ou renvoie le DataFrame sans le modifier. La structure de la chaîne reste ainsi intacte tout en prenant en charge les étapes facultatives.

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)

Exporter le résultat de la chaîne de traitement

La dernière étape d’une chaîne pipe() est souvent un export. Vous pouvez enchaîner une fonction d’export personnalisée avec pipe(), ou appeler simplement la méthode d’export native de Pandas après la chaîne. Une étape pipe(save_to_parquet) maintient l’export dans la documentation de la chaîne et garantit qu’il s’exécute toujours sur le DataFrame nettoyé final, et non sur une version intermédiaire.

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

Vérification rapide

Vérifiez votre compréhension des concepts d’analyse des données abordés dans cette leçon.

Récapitulatif de la leçon

Dans cette leçon, vous avez appris à : utiliser pipe() pour enchaîner des fonctions personnalisées avec les méthodes natives de Pandas, construire des étapes de chaîne de traitement réutilisables, paramétrées et testables sous forme de fonctions pures, et ajouter une journalisation de débogage ainsi que des étapes conditionnelles dans une chaîne pipe. Nous allons maintenant étudier comment structurer les étapes de transformation sous forme de fonctions pour une chaîne ETL destinée à la production.

Gratuit pour commencer

Apprends Python avec un tuteur IA — gratuit

Écris et exécute du vrai code dans ton navigateur, obtiens de l'aide instantanée d'un tuteur IA disponible 24h/24, et reprends là où tu t'es arrêté sur le web ou dans l'app.

Cours
30
Leçons
120

Questions Fréquemment Posées

La leçon « Chaînage de méthodes avec pipe() » est-elle gratuite ?

Oui — le texte complet de « Chaînage de méthodes avec pipe() » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Pandas & NumPy Academy, passe à CoddyKit PRO. Le cours Pandas & NumPy Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Chaînage de méthodes avec pipe() » ?

Écrivez des pipelines de transformation de données lisibles avec pipe() pour enchaîner des fonctions personnalisées et les méthodes natives de Pandas. Tu pratiques Pandas & NumPy Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Pandas & NumPy Academy ?

Aucune expérience préalable n'est requise. Pandas & NumPy Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 4 sur 4.

Combien de temps prend la leçon « Chaînage de méthodes avec pipe() » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Pandas & NumPy Academy ?

Oui. Chaque leçon Pandas & NumPy Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. apply() sur les colonnes et les lignes
  2. apply() avec GroupBy
  3. map() et applymap() pour les opérations élément par élément
  4. Chaînage de méthodes avec pipe()
← Retour à Pandas & NumPy Academy