7 min de leitura
Pandas #14 - Remodelando Dados: pivot_table(), melt() e stack()/unstack()
Como transformar o formato de um DataFrame com pivot() e pivot_table(), voltar ao formato longo com melt(), alternar entre linhas e colunas com stack() e unstack(), e criar variáveis dummy com get_dummies().
No post anterior você usou groupby() pra resumir um DataFrame por categoria — o resultado veio numa única coluna, com um índice (ou MultiIndex) representando os grupos. Só que às vezes o formato mais útil pra ler ou exportar esses dados é bem diferente: uma tabela “larga”, com uma categoria por coluna, em vez de uma por linha. Este post cobre exatamente essa transformação de formato: pivot_table(), melt(), stack()/unstack() e get_dummies().
pivot() e pivot_table(): do formato longo pro largo
pivot() transforma valores únicos de uma coluna em novas colunas — útil quando os dados estão no formato “longo” (uma linha por combinação de categoria e valor) e você quer o formato “largo” (uma coluna por categoria).
Exemplo 1 - pivot() com valores já únicos
import pandas as pd
vendas = pd.DataFrame({
"mes": ["jan", "jan", "fev", "fev"],
"produto": ["notebook", "mouse", "notebook", "mouse"],
"unidades": [8, 30, 12, 25]
})
print(vendas.pivot(index="mes", columns="produto", values="unidades"))
A saída é:
produto mouse notebook
mes
fev 25 12
jan 30 8
Cada combinação de mes e produto virou uma célula da nova tabela. Mas pivot() só funciona quando existe no máximo uma linha por combinação — se houver duas linhas com o mesmo mes e produto, ele lança um erro, porque não sabe qual delas usar.
Exemplo 2 - pivot_table() com agregação
pivot_table() resolve exatamente essa limitação: quando existe mais de um valor por combinação, ele agrega (por padrão, com a média) em vez de dar erro.
vendas_repetidas = pd.DataFrame({
"mes": ["jan", "jan", "jan", "fev"],
"produto": ["notebook", "notebook", "mouse", "notebook"],
"unidades": [5, 3, 30, 12]
})
print(vendas_repetidas.pivot_table(index="mes", columns="produto", values="unidades", aggfunc="sum"))
produto mouse notebook
mes
fev NaN 12.0
jan 30.0 8.0
As duas linhas de jan/notebook (5 e 3) foram somadas em 8, porque aggfunc="sum" foi especificado. Sem esse parâmetro, pivot_table() usa a média por padrão — o mesmo tipo de agregação que você já viu em groupby().agg().
Nota: por padrão,
pivot_table()descarta combinações ondevaluesficaria inteiramente vazio (dropna=True) — passedropna=Falsese quiser manter essas combinações “vazias” explicitamente comoNaNna tabela resultante.
melt(): voltando ao formato longo
melt() faz o caminho inverso de pivot(): transforma colunas em linhas, “derretendo” uma tabela larga de volta pro formato longo.
Exemplo 3 - melt() numa tabela larga
tabela_larga = pd.DataFrame({
"produto": ["notebook", "mouse"],
"jan": [8, 30],
"fev": [12, 25]
})
print(tabela_larga.melt(id_vars="produto", var_name="mes", value_name="unidades"))
produto mes unidades
0 notebook jan 8
1 mouse jan 30
2 notebook fev 12
3 mouse fev 25
id_vars diz qual coluna deve continuar identificando cada linha (produto), e as demais colunas (jan, fev) viraram duas colunas novas: uma com o nome da coluna original (mes) e outra com o valor que estava nela (unidades).
stack() e unstack(): alternando entre linhas e colunas
stack() e unstack() fazem uma transformação parecida com melt()/pivot(), só que operando diretamente sobre os níveis do índice, em vez de colunas nomeadas.
Exemplo 4 - stack() empilhando colunas no índice
df_largo = pd.DataFrame({"notebook": [8, 12], "mouse": [30, 25]}, index=["jan", "fev"])
empilhado = df_largo.stack()
print(empilhado)
jan notebook 8
mouse 30
fev notebook 12
mouse 25
dtype: int64
stack() moveu os nomes das colunas pra dentro do índice, criando um segundo nível — o resultado agora é uma Series com um MultiIndex de dois níveis (mês e produto). unstack() desfaz exatamente essa operação, devolvendo as colunas ao lugar original:
print(empilhado.unstack())
notebook mouse
jan 8 30
fev 12 25
Criando variáveis dummy com get_dummies()
Por fim, uma transformação de formato bem específica, muito comum antes de treinar um modelo de machine learning: converter uma coluna categórica em várias colunas binárias, uma pra cada categoria.
Exemplo 5 - get_dummies()
status = pd.DataFrame({"pedido": [1, 2, 3], "status": ["enviado", "entregue", "enviado"]})
print(pd.get_dummies(status["status"]))
entregue enviado
0 False True
1 True False
2 False True
Cada categoria distinta (entregue, enviado) virou uma coluna própria, com True/False indicando se aquela linha pertence a ela — o formato que a maioria dos algoritmos de machine learning espera receber, já que eles não sabem lidar com texto diretamente.
Nota: o parâmetro
drop_first=Trueremove a primeira coluna dummy gerada, já que ela é redundante — se você sabe que uma linha não éentregue, e existem só duas categorias, ela necessariamente éenviado. É uma prática comum pra evitar colinearidade em alguns modelos estatísticos.
Com pivot_table(), melt(), stack()/unstack() e get_dummies(), você já sabe reorganizar a forma de um DataFrame pro que a análise (ou o modelo) exigir. Esse mesmo stack() que acabou de gerar um índice em dois níveis é uma boa deixa pro próximo post: como criar e navegar índices hierárquicos de propósito, com MultiIndex.
Fonte adaptada: Pandas - Pivoting, Pandas - Stacking and Unstacking, Pandas - Melting, Pandas - Computing Dummy Variables
Comentários