Operaciones de agrupación en Pandas (groupby)

groupbyEs una de las funciones más potentes de Pandas. Permite agrupar los datos según una o más columnas y luego realizar operaciones de agregación, transformación o filtrado en cada grupo.


Uso básico de groupby

Agrupación por una sola columna

Ejemplo

import pandas as pd

# Crear datos de ejemplo
df = pd.DataFrame({
    "Departamento": [Tecnología, "Ventas", Tecnología, Operaciones, "Ventas", Tecnología],
    "Nombre": ["Zhang San", "Li Si", Wang Wu, "Zhao Liu", "Qian Qi", "Sun Ba"],
    "Salario": [12000, 15000, 11000, 18000, 14000, 13000]
})

print(Datos originales:)
print(df)
print()

# Agrupar por departamento
grouped = df.groupby("Departamento")
print(fObjeto agrupado: {type(grouped)})
print(f"Número de grupos: {len(grouped)}")
print()

# Ver grupos
print(Datos de cada grupo:)
for name, group in grouped:
    print(f"\n"Departamento: {name}")
    print(group)

Agrupar y agregar

Ejemplo

import pandas as pd

df = pd.DataFrame({
    "Departamento": [Tecnología, "Ventas", Tecnología, Operaciones, "Ventas"],
    "Salario": [12000, 15000, 11000, 18000, 14000]
})

print("Salario promedio por departamento:")
print(df.groupby("Departamento")["Salario"].mean())
print()

print("Suma agrupada por departamento:")
print(df.groupby("Departamento")["Salario"].sum())
print()

print("Conteo agrupado por departamento:")
print(df.groupby("Departamento").size())

Agrupación por múltiples columnas

Ejemplo

import pandas as pd

df = pd.DataFrame({
    "Año": ["2023", "2023", "2024", "2024"],
    "Departamento": [Tecnología, "Ventas", Tecnología, "Ventas"],
    "Salario": [12000, 15000, 13000, 16000]
})

print("Agrupar por año y departamento:")
print(df.groupby(["Año", "Departamento"])["Salario"].sum())
print()

# Salida como DataFrame
result = df.groupby(["Año", "Departamento"]).agg({
    "Salario": "sum"
}).reset_index()
print(DataFrame resultante:)
print(result)

Funciones de agregación comunes

Agregación única

Función Descripción
sum() Suma
mean() Media
median() Mediana
std() Desviación estándar
min() / max() Mínimo/Máximo
count() Conteo
first() / last() Primer/último valor

Ejemplo

import pandas as pd

df = pd.DataFrame({
    "Departamento": [Tecnología, "Ventas", Tecnología, Operaciones],
    "Salario": [12000, 15000, 11000, 18000]
})

# Llamada encadenada a múltiples agregaciones
print(Agregación en cadena:)
print(df.groupby("Departamento")["Salario"].agg(["sum", "mean", "max", "min"]))

Agregación personalizada

Ejemplo

import pandas as pd
import numpy as np

df = pd.DataFrame({
    "Departamento": [Tecnología, "Ventas", Tecnología, Operaciones],
    "Salario": [12000, 15000, 11000, 18000]
})

# Función de agregación personalizada
def range_func(x):
    return x.max() - x.min()

print("Usando funciones personalizadas:")
print(df.groupby("Departamento")["Salario"].agg(range_func))
print()

# Agregación nombrada (recomendado)
print(Agregación con nombre:)
print(df.groupby("Departamento").agg(
Salario mínimo=("Salario", "min"),
Salario máximo=("Salario", "max"),
Salario promedio=("Salario", "mean")
))

transform

transform permite calcular sobre cada grupo manteniendo la forma original de los datos, devolviendo un resultado con la misma forma que los datos originales.

Ejemplo

import pandas as pd

df = pd.DataFrame({
    "Departamento": [Tecnología, "Ventas", Tecnología, Operaciones, "Ventas"],
    "Salario": [12000, 15000, 11000, 18000, 14000]
})

print("datos originales:")
print(df)
print()

# Calcular el salario promedio de cada departamento y transmitirlo a cada fila
df[Salario promedio por departamento] = df.groupby("Departamento")["Salario"].transform("mean")
print("Añadir el salario promedio del departamento:")
print(df)
print()

# Calcular la proporción del salario de cada persona en el departamento
df["Proporción de salario"] = df["Salario"] / df[Salario promedio por departamento]
print(Proporción salarial:)
print(df)

Filtrado con filter

filter puede filtrar los datos según las condiciones de los grupos.

Ejemplo

import pandas as pd

df = pd.DataFrame({
    "Departamento": [Tecnología, "Ventas", Tecnología, Operaciones, "Ventas", Tecnología],
    "Salario": [12000, 15000, 11000, 18000, 14000, 13000]
})

print("datos originales:")
print(df)
print()

# Filtrar departamentos cuyo salario promedio sea mayor que 13000
print(Salario promedio por departamento > 13000:)
filtered = df.groupby("Departamento").filter(lambda x: x["Salario"].mean() > 13000)
print(filtered)
print()

# Filtrar grupos con cantidad mayor que 2
print("Número de miembros > 2:")
filtered2 = df.groupby("Departamento").filter(lambda x: len(x) > 2)
print(filtered2)

apply: funciones personalizadas

apply permite aplicar una función personalizada a cada grupo.

Ejemplo

import pandas as pd
import numpy as np

df = pd.DataFrame({
    "Departamento": [Tecnología, "Ventas", Tecnología, Operaciones],
    "Salario": [12000, 15000, 11000, 18000]
})

# Aplicar una función personalizada a cada grupo
result = df.groupby("Departamento").apply(
    lambda x: pd.Series({
        "Total": x["Salario"].sum(),
        "Media": x["Salario"].mean()
    })
)
print(Resultado de agregación personalizada:)
print(result)

Práctica: análisis de datos de ventas

Ejemplo

import pandas as pd

# Simular datos de ventas
sales = pd.DataFrame({
    "Fecha": pd.date_range("2024-01-01", periods=30, freq="D"),
    "Producto": ["Teléfono móvil", "Computadora", "Tableta"] * 10,
    "Canal": ["En línea"] * 15 + ["Fuera de línea"] * 15,
    "Ventas": [1000, 2000, 1500] * 10
})

print(=== Análisis de datos de ventas ===\n")

# 1. Estadísticas por producto
print("1. Estadísticas por producto:")
product_summary = sales.groupby("Producto")["Ventas"].agg(["sum", "mean", "count"])
print(product_summary)
print()

# 2. Estadísticas por canal
print("2. Estadísticas por canal:")
channel_summary = sales.groupby("Canal")["Ventas"].sum()
print(channel_summary)
print()

# 3. Estadística cruzada por producto y canal
print(3. Estadística cruzada producto × canal:)
cross_summary = sales.groupby(["Producto", "Canal"])["Ventas"].sum().unstack()
print(cross_summary)
print()

# 4. Calcular la proporción de ventas de cada producto
print("4. Proporción de ventas:")
total = sales["Ventas"].sum()
product_pct = sales.groupby("Producto")["Ventas"].sum() / total * 100
print(product_pct.round(2))

groupby es una operación central en el análisis de datos; dominarla permite realizar de manera eficiente diversas tareas de análisis estadístico.

Otras extensiones