QuieroProgramar por Rodri Gonzalez
Data Analysis · Lección 07 de 19

pandas: groupby y pivot

Cuando el director comercial pregunta "¿cuánto factura cada sucursal por mes?", necesitás agrupar miles de transacciones por categoría y calcular totales. groupby es la herramienta que convierte datos transaccionales en reportes ejecutivos. Es el equivalente exacto del GROUP BY de SQL, pero con la potencia de Python.

90–120 min Prerrequisitos: Lección 06 (Transformaciones)
01

Concepto teórico

El patrón Split-Apply-Combine

groupby sigue un patrón de tres pasos que fue formalizado por Hadley Wickham (creador de R y ggplot2):

  1. Split (dividir): pandas divide el DataFrame en grupos según los valores de una columna. Ejemplo: todas las filas de "CABA" en un grupo, todas las de "Rosario" en otro.
  2. Apply (aplicar): se aplica una función de agregación (sum, mean, count, etc.) a cada grupo por separado.
  3. Combine (combinar): los resultados de cada grupo se combinan en un nuevo DataFrame o Serie.
Analogía del profesor: tenés 100 exámenes desordenados. El paso Split es apilarlos por materia (Matemáticas, Historia, Lengua). El paso Apply es calcular el promedio de cada pila. El paso Combine es escribir en un cuadro: "Matemáticas: 7.2, Historia: 6.8, Lengua: 8.1". Eso es groupby.
# Sintaxis básica
df.groupby("columna_para_agrupar")["columna_para_calcular"].funcion()

# Ejemplo concreto
df.groupby("Sucursal")["Ventas"].sum()
# → "Agrupá por sucursal y sumá las ventas de cada una"

Funciones de agregación

Función Qué calcula Equivalente SQL
.sum() Suma total SUM(col)
.mean() Promedio aritmético AVG(col)
.count() Cantidad de filas (no nulas) COUNT(col)
.min() / .max() Mínimo / máximo MIN(col) / MAX(col)
.median() Mediana (no estándar en SQL)
.std() Desviación estándar STDDEV(col)
.first() / .last() Primer / último valor (no estándar)
.nunique() Cantidad de valores únicos COUNT(DISTINCT col)

Múltiples agregaciones con .agg()

El método más poderoso: .agg() te permite aplicar diferentes funciones a diferentes columnas en una sola operación. Es como escribir un SELECT SUM(ventas), AVG(margen), COUNT(*) FROM ... GROUP BY ... en SQL.

# .agg() con diccionario: columna → funciones
df.groupby("Sucursal").agg(
    Ventas_Total = ("Ventas", "sum"),
    Ticket_Prom  = ("Monto", "mean"),
    Operaciones  = ("ID", "count")
)
Named aggregations: la sintaxis Nombre = ("columna", "funcion") te deja ponerle nombre a cada columna resultante directamente. Es más limpio que .agg({"col": ["sum", "mean"]}) que genera MultiIndex en las columnas (difícil de manejar).

Pivot Tables: la tabla dinámica

pivot_table es como las tablas dinámicas de Excel: pone valores de una columna como filas, valores de otra como columnas, y calcula una agregación en la intersección. Es ideal para reportes matriciales.

# Pivot table
pd.pivot_table(
    df,
    values="Ventas",       # Qué calcular
    index="Sucursal",      # Filas
    columns="Mes",         # Columnas
    aggfunc="sum"           # Función de agregación
)
En el trabajo real: los reportes mensuales de gestión que reciben los directores de una empresa son, en esencia, pivot tables. "Ventas por sucursal por mes", "ticket promedio por canal por categoría de producto", "morosidad por zona por segmento". Dominar pivot_table te convierte en la persona que genera esos reportes en 5 minutos en vez de 3 horas en Excel.
02

Ejemplos explicados paso a paso

Ejemplo 1: groupby básico con una columna

El caso fundamental: agrupar transacciones de ventas por sucursal y calcular métricas.

ejemplo_01_groupby.pyPython

        
Hacé clic en ▶ Ejecutar

Ejemplo 2: Agrupar por múltiples columnas

Podés agrupar por dos o más columnas — por ejemplo, ver las ventas de cada vendedor en cada sucursal.

ejemplo_02_multi_group.pyPython

        
Hacé clic en ▶ Ejecutar

Ejemplo 3: .agg() con múltiples funciones

El reporte completo: para cada sucursal queremos la suma, el promedio, el máximo y la cantidad de operaciones, todo de una vez.

ejemplo_03_agg.pyPython

        
Hacé clic en ▶ Ejecutar
Tip profesional: siempre agregá una columna de participación porcentual en tus reportes. Un gerente no solo quiere saber que CABA vendió $80K — quiere saber que CABA representa el 56% del total. El contexto relativo importa más que el número absoluto.

Ejemplo 4: pivot_table — La tabla dinámica

Crear un reporte matricial donde las filas son sucursales, las columnas son canales, y las celdas son el total de ventas.

ejemplo_04_pivot.pyPython

        
Hacé clic en ▶ Ejecutar

Ejemplo 5: Transformaciones dentro de grupos

A veces no querés resumir los datos en menos filas, sino agregar información del grupo a cada fila original. Por ejemplo: "¿cuánto representan las ventas de esta transacción sobre el total de su sucursal?"

ejemplo_05_transform.pyPython

        
Hacé clic en ▶ Ejecutar
transform vs agg: agg() reduce muchas filas a una por grupo (como GROUP BY en SQL). transform() mantiene el mismo número de filas pero agrega la métrica del grupo a cada una (como una window function en SQL). Es la diferencia entre "dame el total de CABA" vs "dime cuánto es el total de CABA en cada fila de CABA".
03

Referencia rápida

Operación Sintaxis Resultado
Agrupar y sumar df.groupby("col")["val"].sum() Serie con totales
Múltiples columnas df.groupby(["c1","c2"]) Grupos multinivel
Named agg .agg(Nom=("col","func")) DataFrame con headers limpios
Pivot table pd.pivot_table(df,...) Tabla matricial
Cross tabulation pd.crosstab(s1, s2) Tabla de frecuencias
Transform .groupby().transform("sum") Serie del mismo largo
Resetear índice .reset_index() Índice → columnas
04

Ejercicios

Nivel 1 · Básico

Ejercicio 1: groupby + sum

Calculá las ventas totales por Ciudad. Imprimí el resultado. Debe incluir 95000 (total de CABA).

ejercicio_01.pyDebe incluir "95000"

          
Hacé clic en ▶ Ejecutar
Nivel 1 · Básico

Ejercicio 2: groupby + mean

Calculá el ticket promedio por Canal. Imprimí el promedio de "Web" redondeado. Debe incluir 25000.

ejercicio_02.pyDebe incluir "25000"

          
Hacé clic en ▶ Ejecutar
Nivel 1 · Básico

Ejercicio 3: groupby + count (conteo)

Contá cuántas operaciones hubo por Ciudad. Debe incluir 3 (CABA tiene 3 operaciones).

ejercicio_03.pyDebe incluir "3"

          
Hacé clic en ▶ Ejecutar
Nivel 2 · Intermedio

Ejercicio 4: Agrupar por dos columnas

Agrupá por Ciudad y Canal, sumá Monto. Imprimí el resultado. Debe incluir 55000 (CABA+Web).

ejercicio_04.pyDebe incluir "55000"

          
Hacé clic en ▶ Ejecutar
Nivel 2 · Intermedio

Ejercicio 5: .agg() con named aggregations

Por cada Ciudad, calculá: venta total, ticket promedio y cantidad de operaciones usando .agg(). Debe incluir 40000 (Rosario total).

ejercicio_05.pyDebe incluir "40000"

          
Hacé clic en ▶ Ejecutar
Nivel 2 · Intermedio

Ejercicio 6: pivot_table básica

Creá una pivot_table con filas = Ciudad, columnas = Canal, valores = Monto (suma). Debe incluir 55000.

ejercicio_06.pyDebe incluir "55000"

          
Hacé clic en ▶ Ejecutar
Nivel 3 · Avanzado

Ejercicio 7: Ranking con sort_values

Agrupá por Vendedor, sumá Monto, ordenálo de mayor a menor e imprimí el nombre del vendedor #1 usando .index[0]. Debe incluir Ana.

ejercicio_07.pyDebe incluir "Ana"

          
Hacé clic en ▶ Ejecutar
Nivel 3 · Avanzado

Ejercicio 8: transform para participación

Usá .transform("sum") para calcular qué porcentaje del total de su ciudad representó cada venta. Imprimí la columna de participación. Debe incluir 31.6.

ejercicio_08.pyDebe incluir "31.6"

          
Hacé clic en ▶ Ejecutar
Nivel 3 · Avanzado

Ejercicio 9: pivot_table con margins

Creá una pivot_table con margins=True de ventas por Sucursal × Mes. Debe incluir la palabra All (la fila/columna de totales).

ejercicio_09.pyDebe incluir "All"

          
Hacé clic en ▶ Ejecutar
Nivel 4 · Desafío

Ejercicio 10: Reporte ejecutivo completo

Generá un reporte con: (1) Ventas totales por sucursal (con .agg), (2) Sucursal con más ventas, (3) Participación % de cada sucursal. El output debe incluir CABA (la sucursal líder).

ejercicio_10_desafio.pyDebe incluir "CABA"

          
Hacé clic en ▶ Ejecutar
05

Resumen y conexión

En la siguiente lección (08 · pandas: merge/join/concat) vas a aprender a combinar tablas de distintas fuentes — como cruzar la tabla de transacciones con la tabla de clientes, un patrón que vas a usar todos los días.

Recursos: pandas docs — GroupBy · pandas docs — Reshaping (pivot)