Skip to content

Pandas MultiIndex: Guia de Indexação Hierárquica

Updated on

MultiIndex desbloqueia hierarquias organizadas para dados de painel, séries temporais e dados reprojetados, mas muitos usuários evitam usá-lo porque a forma de fatiar parece frágil e a ordem dos níveis pode ficar confusa.

  • Problema: Dimensões aninhadas (região + ano, símbolo + campo) ficam confusas quando armazenadas em colunas simples ou em tabelas largas.
  • Agravante: Reestruturações ad hoc levam a nomes de colunas duplicados, ordenações quebradas e erros ao selecionar por múltiplas chaves.
  • Solução: Use um pequeno conjunto de padrões repetíveis: construa o MultiIndex com set_index, faça fatias com segurança usando .loc/.xs, reordene com swaplevel/reorder_levels e reprocesse com stack/unstack.

Want an AI agent that understands your pandas notebooks and MultiIndex slicing?

RunCell is a JupyterLab AI agent that can read your code, analyze DataFrames, understand notebook context, debug errors, and even generate & execute code for you. It works directly inside JupyterLab—no switching windows or copy-pasting.

👉 Try RunCell: runcell.dev (opens in a new tab)


Referência rápida

TarefaMétodoTrecho
Construir níveis a partir de colunasset_indexdf.set_index(["region", "year"]).sort_index()
A partir de produto cartesianopd.MultiIndex.from_productpd.MultiIndex.from_product([regions, years], names=["region", "year"])
Fatiar por nível.loc ou .xsdf.loc[("EMEA", 2024)] ou df.xs("EMEA", level="region")
Reordenar níveisswaplevel, reorder_levelsdf.swaplevel("region", "year")
Remover ou achatardroplevel, reset_indexdf.droplevel("year"), df.reset_index()
Reformatar wide/longunstack / stackdf.unstack("field"), df.stack("field")

Dados de exemplo

import pandas as pd
 
records = [
    ("EMEA", 2023, "revenue", 120),
    ("EMEA", 2023, "profit", 25),
    ("EMEA", 2024, "revenue", 140),
    ("NA", 2024, "revenue", 210),
    ("NA", 2024, "profit", 50),
]
 
df = (
    pd.DataFrame(records, columns=["region", "year", "metric", "value"])
      .set_index(["region", "year", "metric"])
      .sort_index()
)

Criando estruturas MultiIndex

A partir de colunas existentes

sales = raw_df.set_index(["region", "year"]).sort_index()
  • Use sort_index() para fatiamento previsível entre níveis.
  • Mantenha fora do índice as colunas que devem continuar sendo regulares (por exemplo, valores numéricos).

A partir de produto ou tuplas

idx = pd.MultiIndex.from_product(
    [["EMEA", "NA"], [2023, 2024]],
    names=["region", "year"],
)
frame = pd.DataFrame(index=idx, columns=["revenue"]).sort_index()

from_product garante que toda combinação exista; use from_tuples quando você já tem os pares.


Selecionando com MultiIndex

# Um único caminho através da hierarquia
emea_2024 = df.loc[("EMEA", 2024)]
 
# Seção transversal por um nível, mantendo o restante
emea = df.xs("EMEA", level="region")
 
# Seleção parcial com slices (requer índice ordenado)
idx = pd.IndexSlice
subset = df.loc[idx[:, 2024, :], :]
  • .xs (cross-section) é conveniente quando você quer manter os demais níveis intactos.
  • Para hierarquias de séries temporais, ordene o índice e faça fatias com IndexSlice para ganhar legibilidade.

Reordenando e limpando níveis

# Trazer year antes de region
reordered = df.swaplevel("region", "year").sort_index(level=["year", "region"])
 
# Reordenação explícita para 3+ níveis
df_reordered = df.reorder_levels(["metric", "region", "year"])
 
# Remover um nível quando ele não for mais necessário
flat = df.droplevel("metric")
  • swaplevel é rápido para trocar dois níveis adjacentes; reorder_levels lida com ordens arbitrárias.
  • Depois de reordenar, chame sort_index(level=...) para restaurar a ordem monótona necessária para fatiamento.

Reformatando com Stack e Unstack

Transforme tabelas largas em formato longo organizado (e vice-versa) usando níveis do índice como pivôs.

wide = df.unstack("metric")  # valores de metric viram colunas
long_again = wide.stack("metric")
  • Use fill_value= em unstack para substituir combinações ausentes.
  • Para operações do tipo pivot em colunas, combine set_index([...]).unstack() com stack() em vez de laços manuais.

Quando usar MultiIndex vs. colunas

CenárioMultiIndexColunas simples
Rótulos hierárquicos dirigem o fatiamento (region → year → metric)✅ Encaixe natural para .loc/.xs⚠️ Exige filtros/joins repetidos
Layout de relatório wideunstack para colunas sob demanda⚠️ Risco de nomes de colunas duplicados
Merges frequentes em chaves⚠️ Faça reset antes, depois faça merge✅ Mantenha chaves como colunas para joins
Exportar para CSV/Parquetreset_index() antes de gravar✅ Nenhum passo extra

Regra prática: armazene dados com chaves claras como colunas para intercâmbio; use MultiIndex quando fatiamento hierárquico ou reestruturação forem o principal fluxo de trabalho.


Armadilhas comuns e correções

  • Índice não ordenado bloqueia fatiamento: chame sort_index(level=[...]) antes de fatias parciais.
  • Níveis sem nome: defina index.names (ou names= em set_index) para manter claras as fatias e os resets.
  • Saída difícil de ler: df.index.to_frame() expõe os níveis como colunas para inspeção, e reset_index() achata tudo quando você precisa voltar a colunas simples.

Ao padronizar como você constrói, fatia, reordena e reprojeta objetos MultiIndex, você obtém hierarquias organizadas sem a confusão habitual. Combine esses padrões com guias de reestruturação como pandas-pivot-melt e utilitários de séries temporais como pandas-resample para manter dados multidimensionais controlados de ponta a ponta.