stack e unstack com MultiIndex
Mova o nível mais interno das colunas para o índice das linhas com stack() e faça o caminho inverso com unstack().
stack e unstack com MultiIndex é uma aula grátis de Pandas & NumPy Academy no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Pandas & NumPy Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Pandas & NumPy Academy inclui 4 aulas no total.
Introdução a stack e unstack
stack() e unstack() são ferramentas de remodelagem do Pandas que movem dados entre o índice de linhas e o índice de colunas. Elas são especialmente úteis ao trabalhar com DataFrames que têm um MultiIndex em qualquer um dos eixos. stack() pega o nível mais interno das colunas e o transforma no nível mais interno das linhas, enquanto unstack() faz o inverso.
stack(): colunas para linhas
DataFrame.stack() transforma o nível mais interno dos rótulos das colunas no nível mais interno do índice de linhas, produzindo um resultado mais longo e mais estreito. Se o DataFrame original tinha colunas simples (sem múltiplos níveis), o resultado é uma Series com um MultiIndex. Se as colunas tinham vários níveis, stack() reduz os níveis das colunas em um.
import pandas as pd
df = pd.DataFrame({
'Math': [85, 90, 78],
'Science': [92, 88, 95]
}, index=['Alice', 'Bob', 'Carol'])
print(df)
# Math Science
# Alice 85 92
# Bob 90 88
# Carol 78 95
stacked = df.stack()
print(stacked)
# Alice Math 85
# Science 92
# Bob Math 90
# Science 88
# Carol Math 78
# Science 95
# dtype: int64unstack(): linhas para colunas
Series.unstack() (ou DataFrame.unstack()) é o inverso de stack(). Ele pega o nível mais interno do índice de linhas e o transforma em novos rótulos de colunas, produzindo um resultado mais largo. Funcionalmente, isso é semelhante a pivot(), mas opera diretamente sobre o índice, e não sobre os valores das colunas.
stacked = df.stack()
print(type(stacked)) # Series with MultiIndex
# Restore the original wide format
df_restored = stacked.unstack()
print(df_restored)
# Math Science
# Alice 85 92
# Bob 90 88
# Carol 78 95
# Identical to the original df!Selecionando o nível a ser convertido com stack
Para DataFrames com um MultiIndex nas colunas, stack(level) permite escolher qual nível transformar. Passe um número de nível (0 para o mais externo, -1 para o mais interno, que é o padrão) ou o nome de um nível. Da mesma forma, unstack(level) seleciona qual nível do índice de linhas será transformado em colunas. Esse controle detalhado é essencial para navegar por estruturas de dados hierárquicas complexas.
# MultiIndex columns
arrays = [['Math', 'Math', 'Science', 'Science'],
['Q1', 'Q2', 'Q1', 'Q2']]
multi_cols = pd.MultiIndex.from_arrays(arrays, names=['subject', 'quarter'])
df_multi = pd.DataFrame([[85, 90, 92, 88], [78, 80, 95, 91]],
index=['Alice', 'Bob'], columns=multi_cols)
# Stack the 'quarter' level (innermost, level=-1)
print(df_multi.stack(level='quarter').head())unstack() em níveis específicos das linhas
Quando o DataFrame tem um MultiIndex nas linhas (algo comum após um groupby() em várias colunas), você pode aplicar unstack() a um nível específico das linhas para distribuí-lo pelas colunas. Esse é um padrão muito comum para criar resumos no estilo de tabelas de contingência sem chamar explicitamente pivot_table().
# GroupBy produces MultiIndex rows
df2 = pd.DataFrame({
'region': ['East', 'East', 'West', 'West'],
'product': ['A', 'B', 'A', 'B'],
'sales': [100, 150, 120, 200]
})
# MultiIndex result from groupby
multi = df2.groupby(['region', 'product'])['sales'].sum()
print(multi)
# Unstack the product level into columns
wide = multi.unstack('product')
print(wide)
# product A B
# region
# East 100 150
# West 120 200Lidando com valores ausentes em stack/unstack
Quando unstack() é chamado e nem toda combinação de índice de linhas existe para cada nível de coluna, o Pandas preenche as células ausentes com NaN. Por outro lado, por padrão, stack() remove as linhas que são inteiramente NaN. Você pode controlar esse comportamento com o parâmetro dropna: passe stack(dropna=False) para manter as linhas com NaN.
# Incomplete data: West has no product B
df3 = df2[df2['product'] != 'B'].copy()
multi3 = df3.groupby(['region', 'product'])['sales'].sum()
wide3 = multi3.unstack('product', fill_value=0)
print(wide3)
# product A B
# region
# East 100 0 <- B filled with 0 instead of NaN
# West 120 0stack() e depois calcular nas linhas
Um padrão poderoso consiste em aplicar stack() a um DataFrame largo para converter colunas em linhas, executar uma operação por linha, como filtragem ou groupby, e então aplicar unstack() para voltar ao formato largo. Isso elimina a necessidade de escrever laços coluna por coluna e mantém seu código vetorizado e legível. É especialmente útil para aplicar a mesma transformação a todas as colunas simultaneamente.
# Normalise each column by its column mean using stack/compute/unstack
normalised = (
df.stack()
.groupby(level=1)
.transform(lambda s: (s - s.mean()) / s.std())
.unstack()
)
print(normalised.round(2))
# Math Science
# Alice 0.0 0.39
# Bob 1.13 -1.09
# Carol -1.13 0.71stack() para criação de gráficos
Assim como melt(), stack() converte os dados para o formato longo, que é o formato esperado pelo Seaborn e por muitos recursos auxiliares do Matplotlib. A principal diferença é que stack() opera sobre o índice de colunas e preserva a estrutura MultiIndex, enquanto melt() produz um DataFrame longo e plano. Ambos levam a fluxos de trabalho semelhantes para a criação de gráficos.
# Prepare data for line plot using stack
long = df.stack().reset_index()
long.columns = ['student', 'subject', 'score']
print(long)
# student subject score
# 0 Alice Math 85
# 1 Alice Science 92
# ...
# Ready for: sns.barplot(data=long, x='student', y='score', hue='subject')swaplevel() para reordenar o índice
Após aplicar stack, o nível mais interno das linhas corresponde ao nome original da coluna. Às vezes, você quer que o nível externo seja o nome da variável e o nível interno seja o índice original das linhas. Use swaplevel() no MultiIndex para trocar a ordem de dois níveis e, em seguida, sort_index() para restaurar uma ordenação organizada.
stacked = df.stack() # MultiIndex: (student, subject)
swapped = stacked.swaplevel() # MultiIndex: (subject, student)
swapped = swapped.sort_index()
print(swapped)
# subject student
# Math Alice 85
# Bob 90
# Carol 78
# Science Alice 92
# Bob 88
# Carol 95Quando usar stack, melt ou pivot
Escolha stack() ao trabalhar com DataFrames de colunas com MultiIndex e quiser reduzir os níveis das colunas em um. Escolha melt() quando tiver um DataFrame plano e quiser passar do formato largo para o longo, controlando quais colunas se tornam linhas. Escolha pivot()/pivot_table() para passar do formato longo de volta ao largo. Essas três ferramentas atendem a todas as necessidades de remodelagem entre os formatos largo e longo no Pandas.
# Decision guide (comment, not executable standalone):
# MultiIndex columns -> want fewer levels: use stack()
# Flat wide -> need long format for plotting/ML: use melt()
# Long -> need wide summary table: use pivot_table()
# Wide -> back to long: use melt() or stack()
# Example: stack when you have pivot_table output (MultiIndex cols)
tbl = df2.groupby(['region', 'product'])['sales'].sum().unstack()
long_again = tbl.stack().rename('sales').reset_index()
print(long_again)Resumo prático: guia rápido de remodelagem
Veja este modelo mental conciso: stack() — as colunas são agrupadas nas linhas, e o DataFrame fica mais estreito e mais alto. unstack() — as linhas se expandem em colunas, e o DataFrame fica mais largo e mais baixo. melt() — as colunas nomeadas são agrupadas em um par chave-valor (duas novas colunas). pivot_table() — uma coluna de chave-valor se expande em várias colunas. As quatro operações são reversíveis, e saber qual direção seguir é simplesmente uma questão de decidir se a análise desejada prefere o formato largo ou o longo.
# stack/unstack cycle
df_wide = df.copy() # wide format
df_long = df_wide.stack() # long via stack
df_wide2 = df_long.unstack() # back to wide
# melt/pivot cycle
df_melted = df_wide.melt(id_vars=[]) # wide -> long
# df_pivoted = df_melted.pivot(...) # long -> wide
print('Original shape: ', df_wide.shape)
print('After stack: ', df_long.shape)
print('After unstack: ', df_wide2.shape)Verificação rápida
Teste sua compreensão de stack e unstack com MultiIndex nesta lição.
Recapitulação da lição
Nesta lição, você aprendeu que stack() transforma rótulos de colunas no índice de linhas, produzindo um resultado mais longo e mais estreito; unstack() faz o inverso, transformando um nível do índice de linhas em colunas; ambos funcionam com estruturas MultiIndex provenientes de operações groupby; e swaplevel() permite reordenar os níveis do índice. A seguir, exploraremos pd.crosstab() para criar rapidamente tabelas de frequência entre colunas categóricas.
Perguntas Frequentes
A aula “stack e unstack com MultiIndex” é grátis?
Sim — o texto completo de “stack e unstack com MultiIndex” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Pandas & NumPy Academy, atualize para CoddyKit PRO. O curso de Pandas & NumPy Academy inclui 4 aulas no total.
O que vou aprender em “stack e unstack com MultiIndex”?
Mova o nível mais interno das colunas para o índice das linhas com stack() e faça o caminho inverso com unstack(). Você pratica Pandas & NumPy Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Pandas & NumPy Academy?
Nenhuma experiência prévia é necessária. Pandas & NumPy Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.
Quanto tempo leva a aula “stack e unstack com MultiIndex”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Pandas & NumPy Academy?
Sim. Cada aula de Pandas & NumPy Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- pivot_table: tabulação cruzada
- melt: do formato largo ao longo
- stack e unstack com MultiIndex
- crosstab para tabelas de frequência