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á



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:

PYTHON
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!
TEXT 📖 Somente leitura
> **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 ⭐⭐)

TEXT 📖 Somente leitura
> **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.
PYTHON
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
TEXT 📖 Somente leitura
> **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:

100%
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"]
TEXT 📖 Somente leitura
> **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 ⭐)

TEXT 📖 Somente leitura
> **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.
PYTHON
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'>
TEXT 📖 Somente leitura
> **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 ⭐)

TEXT 📖 Somente leitura
> **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.
PYTHON
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'
TEXT 📖 Somente leitura
> **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 ⭐)

TEXT 📖 Somente leitura
> **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.
PYTHON
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
TEXT 📖 Somente leitura
> **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:

  1. A união de ambos os Índices é computada
  2. Rótulos correspondentes são operados
  3. Rótulos não correspondentes são preenchidos com NaN
100%
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}"]
TEXT 📖 Somente leitura
> **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 ⭐⭐)

TEXT 📖 Somente leitura
> **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.
PYTHON
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
TEXT 📖 Somente leitura
> **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_value se 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 ⭐⭐)

TEXT 📖 Somente leitura
> **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.
PYTHON
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)
TEXT 📖 Somente leitura
> **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 ⭐⭐)

TEXT 📖 Somente leitura
> **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.
PYTHON
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
TEXT 📖 Somente leitura
> **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 ⭐)

TEXT 📖 Somente leitura
> **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.
PYTHON
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]
TEXT 📖 Somente leitura
> **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 ⭐⭐⭐)

TEXT 📖 Somente leitura
> **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.
PYTHON
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)
TEXT 📖 Somente leitura
> **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_unique para 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 com df.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


📝 Exercícios

  1. Básico (Dificuldade ⭐): Crie uma Series com dados de população de 5 cidades. Use set_index e reset_index em um DataFrame para converter entre colunas e índice, e observe como o índice muda.
  2. Intermediário (Dificuldade ⭐⭐): Crie duas Series com Índices parcialmente sobrepostos. Adicione-as usando tanto o operador + quanto add(fill_value=0), e então compare as diferenças. Depois, use o método align para alinhar ambas as Series.
  3. Desafio (Dificuldade ⭐⭐⭐): Use DatetimeIndex para criar dois meses de dados de vendas (janeiro e fevereiro, com datas diferentes). Use reindex para 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.

← Previous: DataFrame Core · Next: Data Types →

Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%