Pandas: Sistema de Índice
Última atualização: 2026-08-26
O Index é o recurso mais subestimado, porém mais poderoso do Pandas. É muito mais do que um "rótulo de linha" — o Index é o mecanismo central por trás do alinhamento de dados, atuando como a "chave" que corresponde automaticamente aos valores quando Series e DataFrames interagem em operações aritméticas. Ao entender o Index, você entende por que o Pandas é mais adequado para análise de dados do que o NumPy. Esta seção aprofunda a natureza, os tipos e a mecânica de alinhamento do Index.
Nota: O código abaixo deve ser executado em um ambiente local Python.
1. O Que Você Aprenderá
- ❶ A natureza e hierarquia de tipos do Índice
- ❷ Operações set_index / reset_index
- ❸ Alinhamento de Índice (a característica mais importante do Pandas)
- ❹ reindex e align
- ❺ Propriedades e métodos comuns do Índice
2. O Problema de Alinhamento de Vendas de Dois Meses da Alice
(1) O Ponto de Dor: Linhas Desalinhadas
A cafeteria da Alice tem dias de operação diferentes em janeiro e fevereiro (31 dias em janeiro, 28 em fevereiro), e em alguns dias a loja estava fechada. Ela precisa mesclar e comparar os dados dos dois meses:
import pandas as pd
# Vendas de janeiro (alguns dias fechados)
jan = pd.Series({'Mon': 320, 'Tue': 280, 'Wed': 350, 'Thu': 410, 'Fri': 390})
# Vendas de fevereiro (dias diferentes, Mon/Tue fechados)
feb = pd.Series({'Wed': 370, 'Thu': 420, 'Fri': 400, 'Sat': 550, 'Sun': 510})
# Estilo NumPy: simplesmente adicionaria posição por posição — ERRADO!
# Pandas: alinha automaticamente pelo rótulo do índice
total = jan + feb
print(total)
# Fri 790.0 ← correspondência!
# Mon NaN ← apenas em jan
# Sat NaN ← apenas em feb
# Sun NaN ← apenas em feb
# Thu 830.0 ← correspondência!
# Tue NaN ← apenas em jan
# Wed 720.0 ← correspondência!
> **Saída:** Execute isso em um ambiente Python local (pandas 2.x). O servidor Piston não tem pandas pré-instalado — instale localmente (`pip install pandas`) para acompanhar. Os valores reais podem variar ligeramente dependendo da sua versão do pandas.
(2) A Solução: Alinhamento Automático de Índice
Quando o Pandas realiza operações aritméticas, ele alinha automaticamente pelo rótulo do Índice — valores com rótulos correspondentes são somados, enquanto rótulos não correspondentes são preenchidos com NaN. Você nunca precisa corresponder manualmente as linhas de dados.
▶ Exemplo: Operações de Alinhamento e fill_value (Dificuldade ⭐⭐)
> **Saída:** Execute isso em um ambiente Python local (pandas 2.x). O servidor Piston não tem pandas pré-instalado — instale localmente (`pip install pandas`) para acompanhar. Os valores reais podem variar ligeramente dependendo da sua versão do pandas.
import pandas as pd
jan = pd.Series({'Mon': 320, 'Tue': 280, 'Wed': 350, 'Thu': 410, 'Fri': 390})
feb = pd.Series({'Wed': 370, 'Thu': 420, 'Fri': 400, 'Sat': 550, 'Sun': 510})
# Preenche dados faltantes com 0 para uma comparação mais limpa
total = jan.add(feb, fill_value=0)
print(total.sort_index())
# Fri 790.0
# Mon 320.0 ← apenas jan, feb=0
# Sat 550.0 ← apenas feb, jan=0
# Sun 510.0 ← apenas feb, jan=0
# Thu 830.0
# Tue 280.0 ← apenas jan, feb=0
# Wed 720.0
> **Saída:** Execute isso em um ambiente Python local (pandas 2.x). O servidor Piston não tem pandas pré-instalado — instale localmente (`pip install pandas`) para acompanhar. Os valores reais podem variar ligeramente dependendo da sua versão do pandas.
(3) O Benefício: O Alinhamento de Índice Previne Bugs Sutis
Se você usasse NumPy para adicionar por posição, jan[0] + feb[0] daria 320 + 370 = 690 — mas Segunda e Quarta não são o mesmo dia de jeito nenhum! O alinhamento de índice libera você da abordagem propensa a erros de "correspondência posicional".
3. A Natureza e os Tipos de Índice
(1) O Índice Não é um Array Comum
Um Índice é um objeto imutável, semelhante a um ndarray, projetado especificamente para indexação baseada em rótulos e alinhamento. Suas características principais:
- Imutável: Não pode ser modificado após a criação (garante a segurança dos dados)
- Hashável: Pode servir como chaves de dicionário ou elementos de conjunto
- Duplicatas permitidas: Permite rótulos repetidos (embora isso degrade o desempenho)
- Múltiplos subtipos: RangeIndex / DatetimeIndex / CategoricalIndex, etc.
graph TB
IDX["Index (Base)"] --> RI["RangeIndex<br/>auto-gerado 0,1,2,..."]
IDX --> DI["DatetimeIndex<br/>rótulos baseados no tempo"]
IDX --> CI["CategoricalIndex<br/>conjunto finito de categorias"]
IDX --> MI["MultiIndex<br/>rótulos hierárquicos"]
IDX --> GI["General Index<br/>rótulos arbitrários"]
> **Saída:** Execute isso em um ambiente Python local (pandas 2.x). O servidor Piston não tem o pandas pré-instalado — instale-o localmente (`pip install pandas`) para acompanhar. Os valores reais podem variar ligeiramente dependendo da sua versão do pandas.
(2) Comparação dos Tipos de Índice
| Tipo | Como Criar | Caso de Uso Típico | Características Especiais |
|---|---|---|---|
| RangeIndex | Padrão | Quando nenhum índice é especificado | Eficiente em memória |
| Index | Especificado manualmente | Rótulos de string/numéricos | Uso geral |
| DatetimeIndex | pd.date_range | Séries temporais | Frequência/offset/reamostragem |
| CategoricalIndex | dtype='category' | Categorias finitas | Categorias ordenadas/não ordenadas |
| MultiIndex | from_tuples/from_product | Dados hierárquicos | Seleção multinível |
▶ Exemplo: Inspeção do Tipo de Índice (Dificuldade ⭐)
> **Saída:** Execute isso em um ambiente Python local (pandas 2.x). O servidor Piston não tem o pandas pré-instalado — instale-o localmente (`pip install pandas`) para acompanhar. Os valores reais podem variar ligeiramente dependendo da sua versão do pandas.
import pandas as pd
# RangeIndex (padrão)
s1 = pd.Series([1, 2, 3])
print(type(s1.index)) # <class 'pandas.core.indexes.range.RangeIndex'>
# General Index (rótulos de string)
s2 = pd.Series([1, 2, 3], index=['a', 'b', 'c'])
print(type(s2.index)) # <class 'pandas.core.indexes.base.Index'>
# DatetimeIndex
dates = pd.date_range('2026-01-01', periods=5)
s3 = pd.Series([100, 200, 150, 300, 250], index=dates)
print(type(s3.index)) # <class 'pandas.core.indexes.datetimes.DatetimeIndex'>
> **Saída:** Execute isso em um ambiente Python local (pandas 2.x). O servidor Piston não tem o pandas pré-instalado — instale-o localmente (`pip install pandas`) para acompanhar. Os valores reais podem variar ligeiramente dependendo da sua versão do pandas.
4. set_index e reset_index
(1) set_index: Transformar uma Coluna em Rótulos de Linha
▶ Exemplo: Uso do set_index (Dificuldade ⭐)
> **Saída:** Execute isso em um ambiente Python local (pandas 2.x). O servidor Piston não tem pandas pré-instalado — instale localmente (`pip install pandas`) para acompanhar. Os valores reais podem variar ligeiramente dependendo da sua versão do pandas.
import pandas as pd
df = pd.DataFrame({
'product': ['Coffee', 'Tea', 'Juice'],
'price': [4.50, 3.80, 5.20],
'category': ['Hot', 'Hot', 'Cold']
})
# Set product as index
df_indexed = df.set_index('product')
print(df_indexed)
# price category
# product
# Coffee 4.50 Hot
# Tea 3.80 Hot
# Juice 5.20 Cold
print(df_indexed.loc['Coffee', 'price']) # 4.5
# Drop the column after setting (default=True)
# Keep the column: drop=False
df_keep = df.set_index('product', drop=False)
print(df_keep.columns) # still has 'product'
> **Saída:** Execute isso em um ambiente Python local (pandas 2.x). O servidor Piston não tem pandas pré-instalado — instale localmente (`pip install pandas`) para acompanhar. Os valores reais podem variar ligeiramente dependendo da sua versão do pandas.
(2) reset_index: Restaurar Rótulos de Linha de Volta para uma Coluna
▶ Exemplo: Uso do reset_index (Dificuldade ⭐)
> **Saída:** Execute isso em um ambiente Python local (pandas 2.x). O servidor Piston não tem pandas pré-instalado — instale localmente (`pip install pandas`) para acompanhar. Os valores reais podem variar ligeiramente dependendo da sua versão do pandas.
import pandas as pd
df = pd.DataFrame({
'price': [4.50, 3.80, 5.20]
}, index=['Coffee', 'Tea', 'Juice'])
# Reset index back to column
df_reset = df.reset_index()
print(df_reset)
# index price
# 0 Coffee 4.50
# 1 Tea 3.80
# 2 Juice 5.20
# Name the new column
df_reset2 = df.reset_index(names='product')
print(df_reset2.columns) # Index(['product', 'price'])
# Drop index entirely (don't keep as column)
df_drop = df.reset_index(drop=True)
print(df_drop)
# price
# 0 4.50
# 1 3.80
# 2 5.20
> **Saída:** Execute isso em um ambiente Python local (pandas 2.x). O servidor Piston não tem pandas pré-instalado — instale localmente (`pip install pandas`) para acompanhar. Os valores reais podem variar ligeiramente dependendo da sua versão do pandas.
(3) Comparação entre set_index e reset_index
| Operação | set_index | reset_index |
|---|---|---|
| Direção | Coluna → rótulos de linha | Rótulos de linha → coluna |
| Coluna original | Removida por padrão (drop=True) | Mantida como uma nova coluna |
| Índice padrão | Nenhuma (deve especificar uma coluna) | RangeIndex (0,1,2,...) |
| Modificação in-place | Não por padrão (inplace=False) | Não por padrão |
5. Alinhamento de Índices em Profundidade
(1) Regras de Alinhamento
Quando dois objetos Pandas (Series ou DataFrames) são combinados em uma operação:
- A união de ambos os Índices é computada
- Rótulos correspondentes são operados
- Rótulos não correspondentes são preenchidos com NaN
graph LR
A["Series A<br/>{a:1, b:2, c:3}"] --> ADD["A + B"]
B["Series B<br/>{b:20, c:30, d:40}"] --> ADD
ADD --> R["Resultado<br/>{a:NaN, b:22, c:33, d:NaN}"]
> **Saída:** Execute isso em um ambiente Python local (pandas 2.x). O servidor Piston não tem o pandas pré-instale — instale localmente (`pip install pandas`) para acompanhar. Os valores reais podem variar levemente dependendo da sua versão do pandas.
▶ Exemplo: Alinhamento de DataFrame (Dificuldade ⭐⭐)
> **Saída:** Execute isso em um ambiente Python local (pandas 2.x). O servidor Piston não tem o pandas pré-instale — instale localmente (`pip install pandas`) para acompanhar. Os valores reais podem variar levemente dependendo da sua versão do pandas.
import pandas as pd
df1 = pd.DataFrame({'A': [1, 2, 3]}, index=['x', 'y', 'z'])
df2 = pd.DataFrame({'A': [10, 20, 30]}, index=['y', 'z', 'w'])
resultado = df1 + df2
print(resultado)
# A
# w NaN
# x NaN
# y 22.0
# z 33.0
# Com fill_value
resultado2 = df1.add(df2, fill_value=0)
print(resultado2)
# A
# w 30.0
# x 1.0
# y 22.0
# z 33.0
> **Saída:** Execute isso em um ambiente Python local (pandas 2.x). O servidor Piston não tem o pandas pré-instale — instale localmente (`pip install pandas`) para acompanhar. Os valores reais podem variar levemente dependendo da sua versão do pandas.
Dica: O alinhamento de índice ocorre não apenas com os operadores +, -, *, /, mas também com métodos como add/sub/mul/div. O parâmetro
fill_valuese aplica apenas ao lado que está com um rótulo faltante — se ambos os lados estiverem faltando, o resultado ainda é NaN.
6. reindex e alinhar
(1) reindex: Remodelar o Índice
▶ Exemplo: Uso do reindex (Dificuldade ⭐⭐)
> **Saída:** Execute isso em um ambiente Python local (pandas 2.x). O servidor Piston não tem pandas pré-instale-o localmente (`pip install pandas`) para acompanhar. Os valores reais podem variar ligeramente dependendo da sua versão do pandas.
import pandas as pd
s = pd.Series([320, 280, 350], index=['Mon', 'Tue', 'Wed'])
# Reindexar para incluir novos rótulos (preencher com NaN)
s_full = s.reindex(['Mon', 'Tue', 'Wed', 'Thu', 'Fri'])
print(s_full)
# Mon 320.0
# Tue 280.0
# Wed 350.0
# Thu NaN
# Fri NaN
# Preencher valores ausentes
s_filled = s.reindex(['Mon', 'Tue', 'Wed', 'Thu', 'Fri'], fill_value=0)
print(s_filled)
# Preenchimento para frente (usar valor anterior)
s_ffill = s.reindex(['Mon', 'Tue', 'Wed', 'Thu', 'Fri'], method='ffill')
print(s_ffill)
# Thu recebe o valor de Wed (350)
> **Saída:** Execute isso em um ambiente Python local (pandas 2.x). O servidor Piston não tem pandas pré-instale-o localmente (`pip install pandas`) para acompanhar. Os valores reais podem variar ligeramente dependendo da sua versão do pandas.
(2) align: Alinhar Duas Series Juntas
▶ Exemplo: Método align (Dificuldade ⭐⭐)
> **Saída:** Execute isso em um ambiente Python local (pandas 2.x). O servidor Piston não tem pandas pré-instale-o localmente (`pip install pandas`) para acompanhar. Os valores reais podem variar ligeramente dependendo da sua versão do pandas.
import pandas as pd
s1 = pd.Series({'a': 1, 'b': 2, 'c': 3})
s2 = pd.Series({'b': 20, 'c': 30, 'd': 40})
# Alinhar ambas ao índice da união
s1_aligned, s2_aligned = s1.align(s2)
print(s1_aligned)
# a 1.0
# b 2.0
# c 3.0
# d NaN
print(s2_aligned)
# a NaN
# b 20.0
# c 30.0
# d 40.0
# Alinhar com fill_value
s1_f, s2_f = s1.align(s2, fill_value=0)
print(s1_f)
# a 1
# b 2
# c 3
# d 0
> **Saída:** Execute isso em um ambiente Python local (pandas 2.x). O servidor Piston não tem pandas pré-instale-o localmente (`pip install pandas`) para acompanhar. Os valores reais podem variar ligeramente dependendo da sua versão do pandas.
(3) Comparação entre reindex e align
| Método | Propósito | Caso de Uso |
|---|---|---|
| reindex | Remodelar um único objeto para um novo índice | Expandir ou reordenar o índice |
| align | Alinhar dois objetos simultaneamente | Correspondência entre dois objetos |
7. Propriedades e Métodos Comuns de Índices
(1) Referência Rápida
| Propriedade/Método | Descrição | Resultado do Exemplo |
|---|---|---|
idx.is_unique |
Se todos os rótulos são únicos | True / False |
idx.is_monotonic_increasing |
Se os rótulos são monotonamente crescentes | True / False |
idx.has_duplicates |
Se existem duplicatas | True / False |
idx.nunique() |
Número de valores únicos | 7 |
idx.duplicated() |
Máscara booleana de duplicatas | Array booleano |
idx.drop_duplicates() |
Remove duplicatas | Novo Índice |
▶ Exemplo: Inspeção de Propriedades do Índice (Dificuldade ⭐)
> **Saída:** Execute isso em um ambiente Python local (pandas 2.x). O servidor Piston não tem o pandas pré-instalado — instale-o localmente (`pip install pandas`) para acompanhar. Os valores reais podem variar ligeiramente dependendo da sua versão do pandas.
import pandas as pd
idx1 = pd.Index(['a', 'b', 'c', 'd'])
idx2 = pd.Index(['a', 'b', 'b', 'c'])
print(idx1.is_unique) # True
print(idx2.is_unique) # False
print(idx2.has_duplicates) # True
print(idx1.nunique()) # 4
print(idx2.duplicated()) # [False, False, True, False]
> **Saída:** Execute isso em um ambiente Python local (pandas 2.x). O servidor Piston não tem o pandas pré-instalado — instale-o localmente (`pip install pandas`) para acompanhar. Os valores reais podem variar ligeiramente dependendo da sua versão do pandas.
8. Exemplo Completo: Alinhamento e Reorganização de Dados de Vendas Mensais
▶ Exemplo: Fluxo de Trabalho de Alinhamento de Vendas de Dois Meses (Dificuldade ⭐⭐⭐)
> **Saída:** Execute isso em um ambiente Python local (pandas 2.x). O servidor Piston não tem o pandas pré-instalado — instale-o localmente (`pip install pandas`) para acompanhar. Os valores reais podem variar ligeiramente dependendo da sua versão do pandas.
import pandas as pd
import numpy as np
# ============================================
# Comprehensive example: Monthly sales data
# alignment and reorganization using Index
# ============================================
# 1. Two months of daily sales (different days)
jan = pd.Series({
'2026-01-06': 320, '2026-01-07': 280, '2026-01-08': 350,
'2026-01-09': 410, '2026-01-10': 390
}, name='jan_sales')
feb = pd.Series({
'2026-02-04': 370, '2026-02-05': 420, '2026-02-06': 400,
'2026-02-07': 550
}, name='feb_sales')
# 2. Index info
print("=== Index Analysis ===")
print(f"Jan unique: {jan.index.is_unique}") # True
print(f"Feb unique: {feb.index.is_unique}") # True
# 3. Align both months to common format
jan_a, feb_a = jan.align(feb, fill_value=0)
print(f"\n=== Aligned Data ===")
comparison = pd.DataFrame({'jan': jan_a, 'feb': feb_a})
print(comparison)
# 4. Set index on DataFrame for label-based access
df = pd.DataFrame({
'product': ['Latte', 'Cappuccino', 'Espresso', 'Mocha', 'Americano'],
'price': [5.50, 4.80, 3.50, 5.20, 3.00],
'category': ['Specialty', 'Specialty', 'Classic', 'Specialty', 'Classic']
})
print(f"\n=== Products by Category ===")
df_cat = df.set_index('category')
print(df_cat.loc['Specialty', ['product', 'price']])
# 5. Reindex to ensure all weekdays present
weekday_sales = pd.Series(
[320, 280, 350, 410, 390],
index=['Mon', 'Tue', 'Wed', 'Thu', 'Fri']
)
full_week = weekday_sales.reindex(
['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
fill_value=0
)
print(f"\n=== Full Week Sales ===")
print(full_week)
> **Saída:** Execute isso em um ambiente Python local (pandas 2.x). O servidor Piston não tem o pandas pré-instalado — instale-o localmente (`pip install pandas`) para acompanhar. Os valores reais podem variar ligeiramente dependendo da sua versão do pandas.
❓ Perguntas Frequentes
Q: Um Índice pode ter rótulos duplicados? R: Sim. O Pandas permite rótulos de Índice duplicados, mas acessar um rótulo duplicado retorna múltiplos valores (uma Series em vez de um escalar), e o desempenho é prejudicado. Use
s.index.is_uniquepara verificar a unicidade. É uma boa prática manter o Índice único sempre que possível.
Q: O set_index perde dados? R: Por padrão, drop=True remove a coluna do DataFrame e a transforma no Índice. Se você precisar manter a coluna, use
df.set_index('col', drop=False). As informações do Índice podem sempre ser restauradas para uma coluna através do reset_index.
Q: Quando o alinhamento é acionado? *R: Todas as operações binárias (+, -, , /, add, sub, etc.) acionam automaticamente o alinhamento de Índice. Operadores de comparação (>, <, ==) também alinham. Operações de atribuição (s1[s1 > 0] = ...) não acionam alinhamento. Operações entre DataFrames alinham tanto no Índice de linhas quanto nos rótulos de colunas simultaneamente.
Q: Qual é a diferença entre reindex e loc? R: reindex pode introduzir novos rótulos (preenchidos com fill_value), enquanto loc só pode acessar rótulos existentes (acessar um rótulo inexistente levanta um KeyError). O propósito do reindex é "remodelar o índice para um formato especificado", enquanto o propósito do loc é "selecionar dados por rótulo".
Q: Quando devo usar o CategoricalIndex? R: Quando os rótulos vêm de um conjunto finito de categorias (por exemplo, dias da semana, meses, nomes de estados), o CategoricalIndex economiza memória e impõe o domínio dos rótulos. Por exemplo, use o CategoricalIndex para garantir que o reindex produza todos os sete dias da semana.
Q: Se o Índice é imutável, como posso alterá-lo? R: O próprio objeto Index é imutável, mas você pode substituí-lo completamente com
df.index = new_index, ou renomear rótulos comdf.rename(index=...). Você não pode atribuir a elementos individuais de um Index.
Q: O que o parâmetro drop no reset_index faz? R: Com drop=True, o Índice original é descartado (não mantido como coluna), fornecendo um RangeIndex limpo. Com drop=False (o padrão), o Índice original é restaurado como uma coluna comum. Um caso de uso comum: após o groupby, chame reset_index(drop=True) para limpar as chaves de agrupamento.
📖 Resumo
- O Índice é o mecanismo central para alinhamento de dados no Pandas — as operações correspondem automaticamente por rótulo
- O Índice é imutável, hashável e permite duplicatas; possui 5 subtipos (Range/Datetime/Categorical/Multi/General)
set_indextransforma uma coluna em rótulos de linha;reset_indexrestaura rótulos de linha de volta para uma coluna- Regra de alinhamento: calcula a união dos Índices, opera nos rótulos correspondentes e preenche rótulos não correspondentes com NaN
reindexreformata o índice de um único objeto;alignalinha simultaneamente dois objetos- Propriedades comuns:
is_unique/has_duplicates/nunique()/duplicated() - Use o parâmetro
fill_valuepara evitar valores NaN desnecessários durante operações aritméticas
📝 Exercícios
- Básico (Dificuldade ⭐): Crie uma Series com dados de população de 5 cidades. Use
set_indexereset_indexem um DataFrame para converter entre colunas e índice, e observe como o índice muda. - Intermediário (Dificuldade ⭐⭐): Crie duas Series com Índices parcialmente sobrepostos. Adicione-as usando tanto o operador
+quantoadd(fill_value=0), e então compare as diferenças. Depois, use o métodoalignpara alinhar ambas as Series. - Desafio (Dificuldade ⭐⭐⭐): Use DatetimeIndex para criar dois meses de dados de vendas (janeiro e fevereiro, com datas diferentes). Use
reindexpara preencher todas as datas para ambos os meses (preencha as faltantes com 0), e então calcule a taxa de crescimento dia a dia entre os dois meses.