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
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:
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:
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:
- Defina a pergunta: exemplo, “quais canais vendem mais com margem positiva?”
- Carregue os dados brutos sem sobrescrever o arquivo original.
- Audite tipos e nulos com
df.info(),df.isna().sum()e amostras de linhas. - Normalize nomes de colunas para evitar erros em joins e filtros.
- Crie métricas derivadas em colunas explícitas, como receita, margem ou mês.
- Valide totais contra uma fonte conhecida antes de apresentar o resultado.
- Exporte o relatório e salve o script/notebook para repetir a análise depois.
Um padrão simples de início de script:
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
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
df = pd.read_excel("dados.xlsx", sheet_name="Planilha1")
JSON
df = pd.read_json("dados.json")
SQL
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:
# 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
# Uma coluna (retorna Series)
nomes = df["nome"]
# Múltiplas colunas (retorna DataFrame)
subset = df[["nome", "salario"]]
Por condição (filtragem)
# 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
# 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
# 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
df = df.rename(columns={"nome": "funcionario", "salario": "remuneracao"})
Ordenando
df_ordenado = df.sort_values("salario", ascending=False)
df_ordenado = df.sort_values(["cidade", "salario"], ascending=[True, False])
Removendo duplicatas e valores nulos
# 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:
# 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:
# 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:
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:
# 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:
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
# 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
dtypesotimizados: converta strings paracategoryquando há poucos valores únicos - Leia apenas as colunas necessárias:
pd.read_csv("dados.csv", usecols=["nome", "salario"]) - Para datasets muito grandes, considere
polarsoudaskcomo alternativas - Evite loops
forsobre 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 Rust — oferece performance superior. Confira nosso comparativo Pandas vs Polars.