Skip to content

Pandas Pivot vs Melt: Como remodelar dados do jeito certo

Updated on

Remodelar dados costuma ser o gargalo antes de analisar ou visualizar. Escolhas erradas duplicam linhas, perdem dados ou criam tabelas largas difíceis de usar.

PAS:

  • Problema: Dados wide/long bagunçados atrasam gráficos e agregações.
  • Agitar: pivot com duplicados gera erro; melt mal usado multiplica linhas ou perde identificadores.
  • Solução: Fluxo tidy—pivot_table quando há duplicados, pivot com chaves únicas, melt para ir a long, stack/unstack para ajustar MultiIndex.

Guia rápido

MétodoDireçãoQuando usarLida com duplicados?
pivotlong → wideChaves únicas🚫 (falha com duplicados)
pivot_tablelong → widePrecisa agregar ou há duplicados✅ via aggfunc
meltwide → longNormalizar colunas em linhasN/A
stack / unstackwide ↔ long em níveis de índiceMultiIndexN/A

Dados de exemplo

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 wide com pivot

wide = sales.pivot(index="region", columns="quarter", values="revenue")
  • Requer combinações únicas de region + quarter.
  • Use .reset_index() para achatar se precisar.

Wide com agregação (pivot_table)

table = sales.pivot_table(
    index="region",
    columns="quarter",
    values="revenue",
    aggfunc="sum",
    margins=True,
    margins_name="Total"
)
  • Lida com duplicados agregando.
  • fill_value=0 deixa o export limpo.

Vários valores e agregações

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

Achatar colunas:

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

Formato long com melt

long = sales.melt(
    id_vars=["region", "quarter"],
    value_vars=["revenue", "units"],
    var_name="metric",
    value_name="value",
)
  • Ideal para libs que esperam tidy data (uma variável por coluna, uma observação por linha).
  • Controle as colunas a desfazer com value_vars.

Stack e unstack para MultiIndex

stacked = table.stack()
unstacked = stacked.unstack()
  • Reorganiza níveis sem redefinir chaves.
  • Selecione o nível com stack(level="quarter") ou unstack(level=-1).

Armadilhas comuns

ProblemaSolução
ValueError: Index contains duplicate entries com pivotUse pivot_table com agregação.
Ordem de colunas inesperadaOrdene: table = table.reindex(sorted(table.columns), axis=1).
MultiIndex pouco legívelAchate após pivot_table.
Valores faltando após reshapefill_value ou stack(dropna=False) para manter vazios.

Dicas de fluxo

  • Normalize primeiro: meltgroupby/aggpivot_table para apresentação.
  • Para gráficos, mantenha os dados long; wide é melhor para relatórios/exports.
  • Depois de pivot_table, exporte: table.to_excel("report.xlsx").

Guias relacionados


Em resumo

  • pivot com chaves únicas, pivot_table quando precisa agregar, melt para ir a long.
  • Achate MultiIndex após pivots complexos para exportar limpo.
  • Combine reshape com groupby para gerar rápido dados prontos para análise.