Astuce Python : la fonction PIPE

Christophe Thibault
10 novembre 2023

Pour continuer dans la série d'articles autour de Python (le premier article Python - Introduction aux décorateurs (decorator) est d’ores et déjà disponible), découvrons la fonction .Pipe. Associé à Pandas, la fonction .Pipe, vous permettra d’améliorer la lisibilité de votre code, grâce à un script Python plus succinct et lisible.

NB : cet article “The PIPE function [python tips]”  est disponible en anglais via le profil linkedin de son auteur Christophe Thibault.

Pour continuer dans la série d'articles autour de Python (le premier article Python - Introduction aux décorateurs (decorator) est d’ores et déjà disponible), découvrons la fonction .Pipe. Associé à Pandas, la fonction .Pipe, vous permettra d’améliorer la lisibilité de votre code, grâce à un script Python plus succinct et lisible.

Qu’est ce que la fonction .pipe de Python ? 

La fonction .pipe peut afficher votre script python dans un formatage plus clair, en  évitant ainsi la répétition de lignes avec certaines transformations ou l'utilisation de fonctions imbriquées,  Il doit être appliqué avec des fonctions qui attendent pd.Series ou DataFrames. Le formatage est DataFrame.pipe(func, *args, **kwargs).

La fonction .pipe de Python en pratique 

Mais plutôt que des mots, allons nous entraîner. Voici l'exemple dans la documentation .pipe.

 <script>

def subtract_federal_tax(df):
    return df * 0.9
def subtract_state_tax(df, rate):
    return df * (1 - rate)
def subtract_national_insurance(df, rate, rate_increase):
    new_rate = rate + rate_increase
    return df * (1 - new_rate)
  <script> 

Deux solutions sont alors possibles : 

  • Créer de nouvelles variables de sortie intermédiaires :

 <script> 

df1 = substract_federal_tax(df)
df2 = substract_state_tax(df1, rate)
....
df_final = subtract_national_insurance(dfn, rate, rate_increase)
<script> 

Utiliser des fonctions imbriquées comme suit :

 <script>


subtract_national_insurance(
    subtract_state_tax(subtract_federal_tax(df), rate=0.12),
    rate=0.05,
    rate_increase=0.02)
    
 <script> 

OU utiliser .pipe sur une ligne :

 <script>

(
    df.pipe(subtract_federal_tax)
    .pipe(subtract_state_tax, rate=0.12)
    .pipe(subtract_national_insurance, rate=0.05, rate_increase=0.02)
)
 <script> 

*args et **kwargs sont des arguments de fonction (respectivement arguments non-mots-clés et arguments de mots-clés).

Les décorateurs et le chaînage de méthode

Voici un exemple en Data Science de Tom Augspurger, utilisant Decorators. Cet article est très utile, avec le chaînage de méthodes en général. Par exemple, pour la fonction load(), le décorateur @log_dtypes modifie la fonction load(), puis ensuite @log_shape modifie quant à lui le résultat de la modification précédente.

 <script>

from functools import wraps
import logging

def log_shape(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        result = func(*args, **kwargs)
        logging.info("%s,%s" % (func.__name__, result.shape))
        return result
    return wrapper

def log_dtypes(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        result = func(*args, **kwargs)
        logging.info("%s,%s" % (func.__name__, result.dtypes))
        return result
    return wrapper


@log_shape
@log_dtypes
def load(fp):
    df = pd.read_csv(fp, index_col=0, parse_dates=True)

@log_shape
@log_dtypes
def update_events(df, new_events):
    df.loc[new_events.index, 'foo'] = new_events
    return df
    
    <script> 

Pour en savoir plus sur la fonction .Pipe, je vous conseille les lectures suivantes : 

Christophe Thibault

D'abord physicien, j'ai basculé dans une vie plus récente en tant que datascientist diplômé de TeleCom ParisTech. La data et le machine learning sont devenus mon quotidien, mais entre deux sessions de debugging, je m'évade sur les notes de ma guitare. Mes journées oscillent entre déchiffrage de scripts et sorties sur des sentiers de nature. Un passionné de data qui jongle entre les algorithmes, les accords de guitare et les trails en pleine nature !