Guia

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.

7 min de leitura

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:

  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:

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 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 Rust — oferece performance superior. Confira nosso comparativo Pandas vs Polars.