Skip to content

Pandas Pivot vs Melt: La forma correcta de reestructurar datos

Updated on

Reformatear datos suele ser el cuello de botella antes de analizar o graficar. Elegir mal puede duplicar filas, perder datos o producir tablas anchas difíciles de usar.

Enfoque PAS:

  • Problema: Datos wide/long desordenados frenan gráficos y agregaciones.
  • Agitar: Usar pivot con duplicados lanza errores; usar melt sin cuidado multiplica filas o pierde identificadores.
  • Solución: Flujo tidy: pivot_table si hay duplicados, pivot si las claves son únicas, melt para ir a long, stack/unstack para ajustar MultiIndex.

Guía rápida

MétodoDirecciónCuándo usar¿Maneja duplicados?
pivotlong → wideClaves únicas🚫 (falla con duplicados)
pivot_tablelong → wideSe necesita agregación o hay duplicados✅ vía aggfunc
meltwide → longNormalizar columnas a filasN/A
stack / unstackwide ↔ long sobre niveles de índiceMultiIndexN/A

Datos de ejemplo

import pandas as pd
 
sales = pd.DataFrame({
    "region": ["NA", "NA", "EU", "EU"],
    "quarter": ["Q1", "Q2", "Q1", "Q2"],
    "product": ["A", "A", "A", "A"],
    "revenue": [120, 140, 110, 150],
    "units": [10, 11, 9, 12],
})

Formato ancho con pivot

wide = sales.pivot(index="region", columns="quarter", values="revenue")
  • Requiere combinaciones únicas de region + quarter.
  • Usa .reset_index() si necesitas aplanar después.

Ancho con agregación (pivot_table)

table = sales.pivot_table(
    index="region",
    columns="quarter",
    values="revenue",
    aggfunc="sum",
    margins=True,
    margins_name="Total"
)
  • Maneja duplicados agregando.
  • fill_value=0 deja la tabla limpia para exportar.

Varios valores y agregaciones

multi = sales.pivot_table(
    index="region",
    columns="quarter",
    values=["revenue", "units"],
    aggfunc={"revenue": "sum", "units": "mean"},
)

Aplanar columnas:

multi.columns = [f"{metric}_{col}" for metric, col in multi.columns]
multi = multi.reset_index()

Formato largo con melt

long = sales.melt(
    id_vars=["region", "quarter"],
    value_vars=["revenue", "units"],
    var_name="metric",
    value_name="value",
)
  • Ideal para bibliotecas que esperan datos tidy (una variable por columna, una observación por fila).
  • Controla qué columnas desanidar con value_vars.

Stack y unstack para MultiIndex

stacked = table.stack()
unstacked = stacked.unstack()
  • Reorganiza niveles sin redefinir claves.
  • Elige nivel con stack(level="quarter") o unstack(level=-1).

Errores comunes

ProblemaSolución
ValueError: Index contains duplicate entries con pivotUsa pivot_table con una agregación.
Orden de columnas inesperadoOrdena: table = table.reindex(sorted(table.columns), axis=1).
MultiIndex difícil de leerAplana columnas tras pivot_table.
Valores faltantes tras reshapeUsa fill_value o stack(dropna=False) para conservar huecos.

Consejos de flujo de trabajo

  • Normaliza primero: meltgroupby/aggpivot_table para presentación.
  • Para gráficos, mantén los datos en largo; wide es mejor para reportes/exportes.
  • Tras pivot_table, exporta a Excel: table.to_excel("report.xlsx").

Guías relacionadas


Puntos clave

  • pivot con claves únicas, pivot_table cuando hay que agregar, melt para ir a largo.
  • Aplana MultiIndex después de pivots complejos para exportar limpio.
  • Combina reshape con groupby para obtener datasets listos rápido.