GroupBy & Agregación
El groupby de pandas implementa split-apply-combine: particiona las filas por claves, ejecuta una función por grupo y une los resultados en un resumen o un frame transformado.
Busca en todas las páginas de la documentación
El groupby de pandas implementa split-apply-combine: particiona las filas por claves, ejecuta una función por grupo y une los resultados en un resumen o un frame transformado.
Tarjeta de receta de referencia rápida - lista para copiar y pegar.
import pandas as pd
summary = (
df.groupby("region", observed=True)["revenue"]
.agg(total="sum", avg="mean", n="count")
.reset_index()
)
pivot = pd.pivot_table(df, index="month", columns="region", values="revenue", aggfunc="sum")Cuándo usar esto:
import pandas as pd
sales = pd.DataFrame(
{
"region": pd.Categorical(["East", "West", "East", "West", "East"]),
"month": ["2025-01", "2025-01", "2025-02", "2025-02", "2025-02"],
"revenue": [120.0, 340.0, 150.0, 280.0, 130.0],
"units": [10, 25, 12, 20, 11],
}
)
# Agregación de métricas múltiples
by_region = (
sales.groupby("region", observed=True)
.agg(revenue_total=("revenue", "sum"), units_avg=("units", "mean"))
.reset_index()
)
# Porcentaje de la cuota regional por fila (transform mantiene el recuento de filas)
sales = sales.copy()
sales["share"] = sales.groupby("region", observed=True)["revenue"].transform(
lambda s: s / s.sum()
)
# Pivoteo para informes
pivot = pd.pivot_table(
sales,
index="month",
columns="region",
values="revenue",
aggfunc="sum",
fill_value=0,
observed=True,
)
print(by_region)
print(sales[["region", "revenue", "share"]])
print(pivot)Lo que esto demuestra:
.agg(col=(field, func))transform para fracciones de grupo a nivel de fila.pivot_table con fill_value para meses dispersos.observed=True en claves categóricas.sum, mean) o una transformación (rank, fillna).as_index=False (el valor predeterminado de pandas 2.x en muchas APIs) devuelve las claves como columnas.| Método | Filas de salida | Uso |
|---|---|---|
agg | Una por grupo | Resúmenes |
transform | Igual que la entrada | Estadísticas por grupo por fila |
apply | Varía | Lógica personalizada de Python (más lento) |
import pandas as pd
# Claves múltiples
df.groupby(["region", "month"], observed=True)["revenue"].sum()
# Filtrar grupos por condición de agregación
df.groupby("region").filter(lambda g: g["revenue"].sum() > 500)dropna=False mantiene los grupos NaN; a menudo es accidental. Solución: dropna=True (predeterminado) o limpiar las claves primero.observed=True. Solución: pasar observed=True en groupby/pivot de pandas 2.x.apply devolviendo formas inconsistentes - rompe el paso de combinación. Solución: preferir agg/transform integrados; vectorizar la lógica personalizada.aggfunc. Solución: elegir sum, mean, o first explícitamente..sort_values("revenue_total", ascending=False).| Alternativa | Usar Cuando | No Usar Cuando |
|---|---|---|
Polars group_by | Agregaciones perezosas (lazy aggregations) más rápidas en datos grandes | Frames pequeños donde pandas ya está cargado |
| DuckDB SQL | Uniones (joins) y agregaciones complejas en una sola consulta | Resúmenes simples de una tabla |
pd.crosstab | Conteo de frecuencias de dos factores | Sumas de ingresos numéricos |
NumPy bincount | Sumas de cubos (buckets) enteros en datos 1-D | Múltiples columnas y manejo de NA |
df.groupby("region")["customer_id"].nunique()df["rank"] = df.groupby("region")["revenue"].rank(ascending=False)df.groupby("region").agg({"revenue": "sum", "units": "max"})apply de Python por grupo es el culpable habitual.agg vectorizado, Polars o DuckDB para millones de filas.out = df.groupby("region").sum().reset_index().agg(total=("revenue", "sum")) nombra las columnas de salida directamente..agg(["sum", "mean"]).df.groupby(pd.Grouper(key="date", freq="ME")) para cubos de fin de mes.df.groupby("region")["revenue"].sum().plot(kind="bar")Grouper y remuestreo (resample)Versiones de la Pila: Esta página fue escrita para Python 3.14.0 (estable 3.14, mantenimiento 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, y uv 0.6+.
Revisado por Chris St. John·Última actualización: 19 jul 2026