---
title: "Análise de Dados com Pandas: Guia"
url: "https://python.dev.br/guias/analise-dados-pandas/"
markdown_url: "https://python.dev.br/guias/analise-dados-pandas.MD"
description: "Aprenda análise de dados com Pandas em Python: DataFrames, CSV/Excel, limpeza, groupby, gráficos, exportação e um checklist atualizado para 2026."
date: "2025-12-10"
author: "Equipe python.dev.br"
---

# Análise de Dados com Pandas: Guia

Aprenda análise de dados com Pandas em Python: DataFrames, CSV/Excel, limpeza, groupby, gráficos, exportação e um checklist atualizado para 2026.


## Introdução

Pandas é a biblioteca mais importante para análise de dados em Python. Usada por cientistas de dados, analistas e engenheiros em todo o mundo, ela permite carregar, manipular, limpar e analisar dados de forma eficiente e intuitiva.

Neste guia, vamos aprender Pandas do básico ao intermediário, com exemplos práticos usando dados reais. A ideia é que você saia com um fluxo completo: importar dados, inspecionar a qualidade, transformar colunas, gerar métricas, criar gráficos simples e exportar um relatório que outra pessoa consiga abrir.

> Resumo rápido: Pandas continua sendo a escolha padrão para análise tabular em Python quando o dataset cabe na memória, a equipe já usa notebooks ou scripts Python e você precisa integrar leitura de CSV/Excel, limpeza, `groupby`, gráficos e exportação com pouco código. Para arquivos muito grandes, compare com Polars ou Dask antes de travar a arquitetura.

## Instalação

```bash
pip install pandas matplotlib openpyxl
```

O `matplotlib` é para gráficos e o `openpyxl` para ler e escrever arquivos Excel.

## Estruturas de dados

O Pandas tem duas estruturas principais:

### Series

Uma coluna de dados com índice:

```python
import pandas as pd

notas = pd.Series([8.5, 7.0, 9.2, 6.8], index=["Ana", "Carlos", "Maria", "Pedro"])
print(notas)
print(f"Média: {notas.mean():.1f}")
print(f"Maior nota: {notas.max()} ({notas.idxmax()})")
```

### DataFrame

Uma tabela com linhas e colunas:

```python
dados = {
    "nome": ["Ana", "Carlos", "Maria", "Pedro"],
    "idade": [25, 30, 22, 28],
    "cidade": ["São Paulo", "Rio de Janeiro", "Curitiba", "Salvador"],
    "salario": [5500, 7200, 4800, 6100],
}

df = pd.DataFrame(dados)
print(df)
```

Saída:

```
     nome  idade          cidade  salario
0     Ana     25       São Paulo     5500
1  Carlos     30  Rio de Janeiro     7200
2   Maria     22        Curitiba     4800
3   Pedro     28        Salvador     6100
```


## Fluxo recomendado em 2026

Antes de sair escrevendo transformações, trate a análise como um pequeno pipeline reprodutível:

1. **Defina a pergunta**: exemplo, “quais canais vendem mais com margem positiva?”
2. **Carregue os dados brutos** sem sobrescrever o arquivo original.
3. **Audite tipos e nulos** com `df.info()`, `df.isna().sum()` e amostras de linhas.
4. **Normalize nomes de colunas** para evitar erros em joins e filtros.
5. **Crie métricas derivadas** em colunas explícitas, como receita, margem ou mês.
6. **Valide totais** contra uma fonte conhecida antes de apresentar o resultado.
7. **Exporte o relatório** e salve o script/notebook para repetir a análise depois.

Um padrão simples de início de script:

```python
from pathlib import Path
import pandas as pd

ARQUIVO = Path("dados/vendas.csv")

df = pd.read_csv(ARQUIVO, parse_dates=["data"])
df.columns = (
    df.columns
    .str.strip()
    .str.lower()
    .str.replace(" ", "_", regex=False)
)

print(df.shape)
print(df.dtypes)
print(df.isna().sum().sort_values(ascending=False).head(10))
```

Esse cuidado evita boa parte dos problemas comuns: coluna com espaço no nome, data lida como texto, número com separador errado e análise impossível de reproduzir.

## Lendo dados de arquivos

### CSV

```python
df = pd.read_csv("dados.csv")
df = pd.read_csv("dados.csv", sep=";", encoding="utf-8")
df = pd.read_csv("dados.csv", parse_dates=["data_nascimento"])
```

### Excel

```python
df = pd.read_excel("dados.xlsx", sheet_name="Planilha1")
```

### JSON

```python
df = pd.read_json("dados.json")
```

### SQL

```python
import sqlite3

conn = sqlite3.connect("banco.db")
df = pd.read_sql("SELECT * FROM clientes", conn)
```

## Explorando os dados

Depois de carregar um DataFrame, explore-o:

```python
# Primeiras e últimas linhas
df.head()       # Primeiras 5 linhas
df.tail(3)      # Ultimas 3 linhas

# Informações gerais
df.info()       # Tipos de dados, valores nulos
df.describe()   # Estatísticas descritivas
df.shape        # (linhas, colunas)
df.columns      # Nomes das colunas
df.dtypes       # Tipos de cada coluna

# Valores únicos
df["cidade"].unique()       # Valores únicos
df["cidade"].nunique()      # Quantidade de valores únicos
df["cidade"].value_counts() # Contagem de cada valor
```

## Selecionando dados

### Por coluna

```python
# Uma coluna (retorna Series)
nomes = df["nome"]

# Múltiplas colunas (retorna DataFrame)
subset = df[["nome", "salario"]]
```

### Por condição (filtragem)

```python
# Filtrar por condição
ricos = df[df["salario"] > 6000]

# Múltiplas condições
filtro = df[(df["idade"] > 25) & (df["salario"] > 5000)]

# Usando isin
cidades = df[df["cidade"].isin(["São Paulo", "Curitiba"])]

# Filtrando strings
df[df["nome"].str.contains("ar")]
df[df["nome"].str.startswith("M")]
```

### Por posição e rótulo

```python
# Por posição (iloc)
df.iloc[0]          # Primeira linha
df.iloc[0:3]        # Linhas 0 a 2
df.iloc[0, 1]       # Linha 0, coluna 1

# Por rótulo (loc)
df.loc[0, "nome"]   # Linha com índice 0, coluna "nome"
df.loc[df["idade"] > 25, ["nome", "salario"]]
```

## Manipulando dados

### Criando novas colunas

```python
# Coluna calculada
df["salario_anual"] = df["salario"] * 12

# Coluna condicional
df["faixa"] = df["salario"].apply(
    lambda x: "Alto" if x > 6000 else "Médio" if x > 5000 else "Inicial"
)

# Usando np.where
import numpy as np
df["senior"] = np.where(df["idade"] >= 28, "Sim", "Não")
```

### Renomeando colunas

```python
df = df.rename(columns={"nome": "funcionario", "salario": "remuneracao"})
```

### Ordenando

```python
df_ordenado = df.sort_values("salario", ascending=False)
df_ordenado = df.sort_values(["cidade", "salario"], ascending=[True, False])
```

### Removendo duplicatas e valores nulos

```python
# Remover duplicatas
df = df.drop_duplicates()
df = df.drop_duplicates(subset=["nome", "cidade"])

# Verificar valores nulos
df.isnull().sum()

# Remover linhas com valores nulos
df = df.dropna()

# Preencher valores nulos
df["salario"] = df["salario"].fillna(df["salario"].median())
df["cidade"] = df["cidade"].fillna("Não informada")
```


## Limpeza rápida de dados reais

Dados de planilha quase sempre chegam com espaços, acentos inconsistentes, números como texto e datas em formatos mistos. Um bloco de limpeza inicial pode poupar horas:

```python
# Remover espaços de textos
colunas_texto = df.select_dtypes(include="object").columns
for coluna in colunas_texto:
    df[coluna] = df[coluna].str.strip()

# Converter moeda brasileira em número
df["valor"] = (
    df["valor"]
    .str.replace("R$", "", regex=False)
    .str.replace(".", "", regex=False)
    .str.replace(",", ".", regex=False)
    .astype(float)
)

# Padronizar datas
df["data"] = pd.to_datetime(df["data"], dayfirst=True, errors="coerce")

# Investigar linhas problemáticas
linhas_sem_data = df[df["data"].isna()]
print(linhas_sem_data.head())
```

Use `errors="coerce"` quando você quer transformar valores inválidos em `NaT`/`NaN` para investigar depois, em vez de deixar o script quebrar no primeiro erro.

## Agrupamento e agregação

O `groupby` é uma das funcionalidades mais poderosas do Pandas:

```python
# Agrupar por cidade e calcular estatisticas
por_cidade = df.groupby("cidade")["salario"].agg(["mean", "min", "max", "count"])
print(por_cidade)

# Múltiplas colunas
resumo = df.groupby("cidade").agg(
    salario_medio=("salario", "mean"),
    idade_media=("idade", "mean"),
    total_funcionarios=("nome", "count"),
)
```

## Exemplo prático: análise de vendas

Vamos criar e analisar um conjunto de dados de vendas:

```python
import pandas as pd
import numpy as np

# Gerar dados de exemplo
np.random.seed(42)
n = 500

vendas = pd.DataFrame({
    "data": pd.date_range("2025-01-01", periods=n, freq="D"),
    "produto": np.random.choice(["Notebook", "Mouse", "Teclado", "Monitor"], n),
    "regiao": np.random.choice(["Sudeste", "Sul", "Nordeste", "Norte"], n),
    "quantidade": np.random.randint(1, 20, n),
    "preco_unitario": np.random.uniform(50, 5000, n).round(2),
})

vendas["total"] = vendas["quantidade"] * vendas["preco_unitario"]
vendas["mes"] = vendas["data"].dt.month
vendas["trimestre"] = vendas["data"].dt.quarter
```

Agora, vamos analisar:

```python
# Resumo geral
print(f"Total de vendas: R$ {vendas['total'].sum():,.2f}")
print(f"Ticket médio: R$ {vendas['total'].mean():,.2f}")
print(f"Período: {vendas['data'].min()} a {vendas['data'].max()}")

# Vendas por produto
por_produto = vendas.groupby("produto").agg(
    receita=("total", "sum"),
    quantidade=("quantidade", "sum"),
    ticket_medio=("total", "mean"),
).sort_values("receita", ascending=False)
print(por_produto)

# Vendas por regiao e trimestre
por_regiao_trim = vendas.pivot_table(
    values="total",
    index="regiao",
    columns="trimestre",
    aggfunc="sum",
)
print(por_regiao_trim)

# Top 10 maiores vendas
top10 = vendas.nlargest(10, "total")[["data", "produto", "total"]]
print(top10)
```

## Visualização com Pandas

O Pandas integra com Matplotlib para gráficos rápidos:

```python
import matplotlib.pyplot as plt

# Gráfico de barras
por_produto["receita"].plot(kind="bar", title="Receita por Produto")
plt.ylabel("Receita (R$)")
plt.tight_layout()
plt.savefig("receita_produto.png")
plt.show()

# Gráfico de linha (evolução mensal)
vendas_mensais = vendas.groupby("mes")["total"].sum()
vendas_mensais.plot(kind="line", marker="o", title="Evolução Mensal de Vendas")
plt.xlabel("Mês")
plt.ylabel("Total (R$)")
plt.tight_layout()
plt.show()
```

## Salvando resultados

```python
# Salvar em CSV
df.to_csv("resultado.csv", index=False, encoding="utf-8")

# Salvar em Excel
df.to_excel("resultado.xlsx", index=False, sheet_name="Dados")

# Salvar múltiplas planilhas
with pd.ExcelWriter("relatorio.xlsx") as writer:
    df.to_excel(writer, sheet_name="Dados", index=False)
    por_produto.to_excel(writer, sheet_name="Por Produto")
```


## Checklist antes de enviar a análise

Antes de mandar uma planilha, gráfico ou dashboard para alguém, faça uma revisão curta:

- O total principal bate com a fonte original?
- Linhas duplicadas foram verificadas?
- Datas estão no fuso/período correto?
- Valores nulos foram removidos, preenchidos ou explicados?
- Gráficos têm título, unidade e legenda quando necessário?
- O script/notebook roda do zero em outra máquina?
- O arquivo exportado não contém dados sensíveis desnecessários?

Para análises recorrentes, prefira salvar um script `.py` ou notebook versionado em Git, com arquivos de entrada separados dos arquivos gerados.

## Dicas de desempenho

- Use `dtypes` otimizados: converta strings para `category` quando há poucos valores únicos
- Leia apenas as colunas necessárias: `pd.read_csv("dados.csv", usecols=["nome", "salario"])`
- Para datasets muito grandes, considere `polars` ou `dask` como alternativas
- Evite loops `for` sobre DataFrames; use operações vetorizadas

## Conclusão

Pandas é uma ferramenta indispensável para quem trabalha com dados em Python. Com DataFrames, você pode carregar dados de praticamente qualquer fonte, limpar, transformar, analisar e visualizar resultados de forma eficiente. Os conceitos de filtragem, agrupamento e agregação apresentados neste guia cobrem a grande maioria das tarefas de análise de dados do dia a dia. A prática com dados reais é o melhor caminho para dominar a biblioteca.

Para datasets muito grandes, o Polars — escrito em <a href="https://rustlang.com.br/blog/" target="_blank" rel="noopener" onclick="umami.track('portfolio-site-click', {source: 'python.dev.br', target: 'rustlang.com.br', content: 'analise-dados-pandas'})">Rust</a> — oferece performance superior. Confira nosso [comparativo Pandas vs Polars](/comparacoes/pandas-vs-polars/).
