Función pipe en Python Polars. ¡No te salgas del pipeline!

¿Estás explorando Polars como una alternativa a Pandas? ¡Nos encanta por la sensación de pipe flow! Aprende en 3 líneas cómo y cuándo usarlo.

Polars Python con mensaje que dice 'pipe'

Polars pipeline. Aplica tus functiones custom (udf) con la función pipe

Bueno, bueno, estás con Python y echas de menos el rollito pipe?? Encadenar transformaciones a dataframes de manera elegante nunca está de más. Pues.. ¡traemos buenas noticias! En nuestra transición de Pandas a Polars a la hora de trabajar con dataframes, la sintaxis de este último nos ha acabado de encandilar.

La función pipedel módulo Polars nos permiten encadenar operaciones pasando el resultado de las mismas como input dde la siguiente operación. Recuerda por ejemplo a los pipes de bash o del ecosistema tidyverse dplyr de R.

Por supuesto, esta no es una de las mejores ventajas que Polars presenta sobre Pandas… ¡pero nos gusta bastante!

Sigue leyendo para descrubir de un vistazo cómo mantenerse en dentro del pipeline con Polars Python!

La función pipe ofrece una forma estructurada de aplicar una secuencia de funciones definidas por el usuario (UDFs). Aquí tienes un ejemplo:

import polars as pl
import random 

# Creamos el Polars DataFrame con las columnas base
df = pl.DataFrame({
    'name': ['Alice', 'Bob', 'Charlie'], 
    'offensive_skill': [5, 30, 85], 
    'defensive_skill': [92, 30, 10]
    })
    
# Definimos las funciones custom que aplicar
def add_position_column(df):
    df = df.with_columns( 
        pl.when(pl.col('defensive_skill') > 50).then('CB')
        .when(pl.col('offensive_skill') > 50).then('FW')
        .otherwise('bench').alias("position")
    )
    return df

def add_squad_number_column(df):
    df = df.with_columns( 
        pl.when(pl.col('position') == 'CD').then(pl.lit(random.sample(range(2, 6), 1)[0], dtype=pl.Int8))
        .when(pl.col('position') == 'FW').then(pl.lit(random.sample(range(7, 19), 1)[0], dtype=pl.Int8))
        .otherwise('-').alias("squad_number")
    )
    return df

# Encadena las operaciones usando la función pipe

(
    df
    .pipe(add_position_column)
    .pipe(add_squad_number_column)
)
shape: (3, 5)
nameoffensive_skilldefensive_skillpositionsquad_number
stri64i64strstr
"Alice"592"CB""-"
"Bob"3030"bench""-"
"Charlie"8510"FW""9"


Polars pipe y ‘lazy evaluation’

Un truco extra a la hora de usar la función pipe de Polars, es el uso de lazy evaluation con el objetivo de maximizar las ventajas de la optimización de query y paralelización.

result = (
    df.lazy()
    .pipe(add_position_column)
    .pipe(add_squad_number_column)
    .collect()
)

result
shape: (3, 5)
nameoffensive_skilldefensive_skillpositionsquad_number
stri64i64strstr
"Alice"592"CB""-"
"Bob"3030"bench""-"
"Charlie"8510"FW""8"

Usando el método .pipe(), podremos separar funcionalidades y mantener el código más mantenible a largo plazo, mientras mantenemos las ventajas de la paralelización de Polars.


Polars user defined functions (udfs)

En este punto, deberías estar convencido de que las expresiones de Polars son tan poderosas y flexibles que hay mucho menos necesidad de funciones personalizadas de Python en comparación con otras bibliotecas.

Sin embargo, aún necesitas tener la capacidad de pasar el estado de una expresión a una biblioteca de terceros o aplicar tu función de caja negra sobre los datos en Polars.


Carlos Vecina
Carlos Vecina
Senior Data Scientist at Jobandtalent

Senior Data Scientist at Jobandtalent | AI & Data Science para aportar valor en la empresa