Pandas & NumPy Academy · Lección

Transform y Filter de GroupBy

Use transform() para añadir estadísticas del grupo como una columna y filter() para conservar solo los grupos que cumplan una condición.

Lección 4 de 413 pasos

Transform y Filter de GroupBy es una lección gratuita de Pandas & NumPy Academy en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Pandas & NumPy Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Pandas & NumPy Academy incluye 4 lecciones en total.

Más allá de la agregación

Después de dominar agg(), surge una pregunta natural: ¿qué ocurre si quiere conservar todas las filas originales, pero enriquecerlas con estadísticas del grupo? ¿O conservar únicamente los grupos que cumplen una condición? Aquí es donde entran en juego transform() y filter(). Estos dos métodos amplían GroupBy más allá de los simples resúmenes, hacia la ingeniería de características y la selección de datos.

Comprender transform()

transform() aplica una función a cada grupo y devuelve un resultado con la misma forma que el DataFrame original: un valor por cada fila original. El resultado del grupo se propaga de vuelta a cada fila que pertenece a ese grupo. Esto lo hace ideal para añadir estadísticas del grupo como nuevas columnas sin cambiar el número de filas.

import pandas as pd

df = pd.DataFrame({
    'dept':   ['Eng', 'HR', 'Eng', 'HR', 'Eng'],
    'salary': [90000, 60000, 95000, 62000, 88000]
})

# Add a column with each employee's department average salary
df['dept_avg'] = df.groupby('dept')['salary'].transform('mean')
print(df)
#    dept  salary    dept_avg
# 0   Eng   90000  91000.000
# 1    HR   60000  61000.000
# 2   Eng   95000  91000.000
# 3    HR   62000  61000.000
# 4   Eng   88000  91000.000

Casos de uso habituales de transform()

Entre las aplicaciones habituales de transform() se incluyen: añadir la media del grupo para normalizar valores, añadir la suma del grupo para calcular el porcentaje del total correspondiente a cada fila y añadir el rango dentro del grupo para ver cómo se compara cada elemento con los demás de su grupo. Todas estas operaciones conservan la forma y el índice originales, por lo que el resultado se puede usar inmediatamente junto con las columnas originales.

# Percentage of each employee's salary within their department total
df['pct_of_dept'] = (
    df['salary'] / df.groupby('dept')['salary'].transform('sum') * 100
).round(1)
print(df[['dept', 'salary', 'pct_of_dept']])
# dept  salary  pct_of_dept
# Eng   90000        33.1
# HR    60000        49.2
# Eng   95000        34.9

Usar una función personalizada en transform()

Al igual que agg(), transform() acepta cualquier objeto invocable, además de nombres de funciones en forma de cadena. La función recibe una Series de valores de un grupo y debe devolver una Series de la misma longitud o un escalar, que se propagará a todas las filas. Devolver un escalar es el caso de uso más habitual; devolver una Series de distinta longitud provocará un error.

# Z-score normalisation within each department
def zscore(s):
    return (s - s.mean()) / s.std()

df['salary_zscore'] = df.groupby('dept')['salary'].transform(zscore)
print(df[['dept', 'salary', 'salary_zscore']].round(2))
# dept  salary  salary_zscore
# Eng   90000          -0.51
# HR    60000          -0.71
# Eng   95000           1.03

agg() frente a transform(), lado a lado

La diferencia clave es la siguiente: agg() reduce el número de filas, dejando una por grupo, mientras que transform() conserva el número de filas, dejando una por cada fila original. Use agg() para crear una tabla resumen. Use transform() para añadir información del grupo como una nueva columna de características en el DataFrame original.

g = df.groupby('dept')['salary']

# agg: 2 rows (one per unique dept)
print(g.agg('mean'))
# dept
# Eng    91000.0
# HR     61000.0

# transform: 5 rows (one per original row)
print(g.transform('mean'))
# 0    91000.0
# 1    61000.0
# 2    91000.0
# 3    61000.0
# 4    91000.0

Comprender filter()

filter() conserva o descarta grupos completos según una función booleana. Debe pasar una función que reciba un sub-DataFrame de un grupo y devuelva True (conservar el grupo) o False (descartar el grupo). El resultado es un subconjunto del DataFrame original que contiene únicamente las filas de los grupos que superaron la prueba.

df2 = pd.DataFrame({
    'dept':   ['Eng', 'HR', 'Eng', 'HR', 'Eng', 'Legal'],
    'salary': [90000, 60000, 95000, 62000, 88000, 70000]
})

# Keep only departments with at least 2 employees
big_depts = df2.groupby('dept').filter(lambda g: len(g) >= 2)
print(big_depts)
# dept, salary rows: Eng(3) and HR(2) remain; Legal(1) dropped

Filtrar por el valor agregado del grupo

Un uso muy habitual de filter() consiste en conservar los grupos cuyo valor agregado alcanza un umbral. Por ejemplo, puede conservar únicamente los departamentos cuyo salario medio supere un objetivo o las categorías de productos cuyas ventas totales superen un mínimo. Esto permite eliminar los grupos con poco volumen antes de realizar análisis adicionales.

# Keep only departments where average salary > 80000
high_paying = df2.groupby('dept').filter(
    lambda g: g['salary'].mean() > 80000
)
print(high_paying)
#    dept  salary
# 0   Eng   90000
# 2   Eng   95000
# 4   Eng   88000
# (HR avg is 61000, filtered out)

Combinar transform() y filter()

Puede aplicar transform() y filter() secuencialmente para enriquecer los datos y después acotarlos. Primero use filter() para eliminar los grupos irrelevantes y, después, use transform() en el resultado filtrado para añadir características del grupo. La combinación proporciona un subconjunto limpio y enriquecido con características, listo para crear modelos o informes.

# Step 1: keep only large departments
filtered = df2.groupby('dept').filter(lambda g: len(g) >= 2)

# Step 2: add group mean salary to the filtered result
filtered = filtered.copy()
filtered['dept_avg'] = filtered.groupby('dept')['salary'].transform('mean')
print(filtered)

transform() para completar valores hacia delante dentro de los grupos

transform() también resulta útil con funciones no numéricas. Un patrón habitual consiste en rellenar los valores ausentes dentro de un grupo usando el relleno hacia delante o la mediana del grupo, lo que suele ser mucho mejor que aplicar un relleno global. Pase una lambda que llame a fillna() sobre la Series del grupo; el resultado tendrá el mismo índice que el DataFrame original.

import numpy as np

df3 = pd.DataFrame({
    'dept':   ['Eng', 'Eng', 'HR', 'HR', 'Eng'],
    'salary': [90000, np.nan, 60000, np.nan, 88000]
})

# Fill NaN with the group mean
df3['salary_filled'] = df3.groupby('dept')['salary'].transform(
    lambda s: s.fillna(s.mean())
)
print(df3)

Patrón práctico: posición relativa

Un caso de uso empresarial muy potente consiste en calcular la posición de cada fila con respecto a su grupo. Al combinar transform() con operaciones aritméticas, puede añadir columnas como: salario menos la media del grupo (desviación), salario como fracción del total del grupo o un indicador booleano que señale si este empleado gana por encima de la mediana del grupo. Estas características resultan extremadamente útiles para cuadros de mando y modelos de ML.

df['dept_total'] = df.groupby('dept')['salary'].transform('sum')
df['pct_of_total'] = (df['salary'] / df['dept_total'] * 100).round(1)
df['above_avg'] = df['salary'] > df.groupby('dept')['salary'].transform('mean')
print(df[['dept', 'salary', 'pct_of_total', 'above_avg']])

Consideraciones de rendimiento

Tanto transform() como filter(), cuando se usan con funciones integradas especificadas como cadenas, son rápidos porque utilizan rutas de código optimizadas. Sin embargo, cuando pasa una lambda o una función personalizada de Python, Pandas debe llamar a esa función una vez por grupo, lo que puede ser lento en datos con muchos grupos. Para obtener el máximo rendimiento con conjuntos de datos grandes, compruebe si su lógica personalizada se puede expresar mediante una función integrada especificada como cadena.

# Slower: custom lambda (called once per group)
df['dept_mean_slow'] = df.groupby('dept')['salary'].transform(lambda s: s.mean())

# Faster: built-in string shortcut (vectorised C path)
df['dept_mean_fast'] = df.groupby('dept')['salary'].transform('mean')

# Both give identical results, but the built-in is significantly faster

Comprobación rápida

Compruebe cuánto ha entendido de GroupBy transform() y filter() en esta lección.

Resumen de la lección

En esta lección ha aprendido que transform() devuelve estadísticas del grupo que se propagan de vuelta hasta recuperar el número de filas original, por lo que resulta ideal para añadir características del grupo; que filter() conserva o elimina grupos completos según una condición booleana; y que combinar ambos métodos permite crear conjuntos de datos enriquecidos y filtrados para análisis posteriores. A continuación exploraremos cómo combinar DataFrames mediante pd.concat.

Gratis para empezar

Aprende Python con un tutor de IA — gratis

Escribe y ejecuta código real en tu navegador, obtén ayuda instantánea de un tutor de IA disponible 24/7 y continúa donde lo dejaste en la web o en la aplicación.

Cursos
30
Lecciones
120

Preguntas frecuentes

¿La lección «Transform y Filter de GroupBy» es gratis?

Sí — el texto completo de «Transform y Filter de GroupBy» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Pandas & NumPy Academy, actualiza a CoddyKit PRO. El curso de Pandas & NumPy Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Transform y Filter de GroupBy»?

Use transform() para añadir estadísticas del grupo como una columna y filter() para conservar solo los grupos que cumplan una condición. Practicas Pandas & NumPy Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Pandas & NumPy Academy?

No se requiere experiencia previa. Pandas & NumPy Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.

¿Cuánto tiempo toma la lección «Transform y Filter de GroupBy»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Pandas & NumPy Academy?

Sí. Cada lección de Pandas & NumPy Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. El patrón Split-Apply-Combine
  2. GroupBy con una o varias claves
  3. El método agg()
  4. Transform y Filter de GroupBy
← Volver a Pandas & NumPy Academy