Pandas: Projeto: Análise Abrangente
Última atualização: 2026-08-26
Projetos do mundo real nunca envolvem apenas uma tabela -- pense em 5 CSVs + 1 arquivo Excel + uma consulta de banco de dados, mesclados 4 vezes, agrupados em 3 dimensões, pivotados em 2 tabelas cruzadas e estilizados em 1 relatório polido. Esta lição é o grande final de todo o curso, reunindo cada habilidade das 24 lições anteriores em um único projeto: integração multi-fonte -> auditoria de qualidade -> junções complexas -> análise multidimensional -> relatório automatizado.
Aviso: O código abaixo deve ser executado em um ambiente Python local.
1. O Que Você Aprenderá
-
- Integração de dados multi-fonte
-
- Auditoria de qualidade de dados
-
- Cadeias complexas de mesclagem
-
- Análise cruzada pivô multidimensional
-
- Relatórios automatizados com Styler
2. Contexto do Projeto: Análise de E-Commerce Transfronteiriço
(1) A Tarefa
Bob precisa analisar os dados do 1º ao 3º trimestre de um negócio de e-commerce transfronteiriço: 4 CSVs (pedidos/produtos/clientes/regiões) + 1 banco de dados SQLite (inventário) -> integrar -> analisar -> relatar.
(2) Fluxo de Trabalho Completo
graph TB
A["Carregar 5 Fontes de Dados"] --> B["Auditoria de Qualidade dos Dados"]
B --> C["Merge de 4 Tabelas"]
C --> D["Pipeline de Limpeza"]
D --> E["Groupby Multidimensional"]
E --> F["Análise Cruzada Pivô"]
F --> G["Relatório Styler"]
G --> H["Exportação Multi-Sheet"]
> **Saída:** Execute em um ambiente Python local (pandas 2.x). O servidor Piston não tem pandas pré-instalado. Por favor, instale localmente (`pip install pandas`) e acompanhe. Os valores reais podem variar ligeiramente dependendo da sua versão do pandas.
3. Carregamento de Dados Multi-Fonte
▶ Exemplo
> **Saída:** Execute em um ambiente Python local (pandas 2.x). O servidor Piston não tem pandas pré-instalado. Por favor, instale localmente (`pip install pandas`) e acompanhe. Os valores reais podem variar ligeiramente dependendo da sua versão do pandas.
: Carregando 5 fontes de dados (Dificuldade: 3/5 estrelas)
import pandas as pd
import numpy as np
import sqlite3
from io import StringIO, BytesIO
# ============================================
# Passo 1: Carregamento de Dados Multi-Fonte
# ============================================
np.random.seed(42)
# Fonte 1: Clientes (CSV)
customers = pd.DataFrame({
'customer_id': range(1, 501),
'name': [f'Customer_{i:04d}' for i in range(1, 501)],
'segment': np.random.choice(['Consumer', 'Corporate', 'Home Office'], 500),
'city': np.random.choice(['New York', 'Los Angeles', 'Chicago', 'Houston', 'London', 'Tokyo'], 500),
'country': np.random.choice(['US', 'US', 'US', 'US', 'UK', 'JP'], 500)
})
# Fonte 2: Produtos (CSV)
products = pd.DataFrame({
'product_id': range(1, 51),
'product_name': [f'Product_{i:02d}' for i in range(1, 51)],
'category': np.random.choice(['Electronics', 'Clothing', 'Home', 'Sports', 'Books'], 50),
'unit_price': np.round(np.random.uniform(10, 500, 50), 2)
})
# Fonte 3: Pedidos (CSV)
orders = pd.DataFrame({
'order_id': [f'ORD-{i:05d}' for i in range(1, 2001)],
'customer_id': np.random.randint(1, 501, 2000),
'product_id': np.random.randint(1, 51, 2000),
'order_date': pd.to_datetime(np.random.choice(
pd.date_range('2024-01-01', '2024-09-30'), 2000)),
'quantity': np.random.randint(1, 10, 2000),
'discount': np.random.choice([0, 0.05, 0.1, 0.2, 0.3], 2000)
})
# Fonte 4: Regiões (Excel)
regions = pd.DataFrame({
'country': ['US', 'UK', 'JP', 'DE', 'FR'],
'region': ['North America', 'Europe', 'Asia Pacific', 'Europe', 'Europe'],
'currency': ['USD', 'GBP', 'JPY', 'EUR', 'EUR']
})
# Fonte 5: Inventário (SQLite)
conn = sqlite3.connect(':memory:')
inventory = pd.DataFrame({
'product_id': range(1, 51),
'stock': np.random.randint(0, 500, 50),
'reorder_level': np.random.randint(20, 100, 50)
})
inventory.to_sql('inventory', conn, index=False, if_exists='replace')
# Carregar do banco de dados
inv_df = pd.read_sql('SELECT * FROM inventory', conn)
conn.close()
print(f"✅ Carregado: customers({len(customers)}), products({len(products)}), "
f"orders({len(orders)}), regions({len(regions)}), inventory({len(inv_df)})")
> **Saída:** Execute em um ambiente Python local (pandas 2.x). O servidor Piston não tem pandas pré-instalado. Por favor, instale localmente (`pip install pandas`) e acompanhe. Os valores reais podem variar ligeiramente dependendo da sua versão do pandas.
4. Auditoria de Qualidade dos Dados
▶ Exemplo
> **Saída:** Execute em um ambiente Python local (pandas 2.x). O servidor Piston não tem pandas pré-instalado. Por favor, instale localmente (`pip install pandas`) e acompanhe. Os valores reais podem variar ligeiramente dependendo da sua versão do pandas.
: Auditoria de qualidade (Dificuldade: 2/5 estrelas)
# ============================================
# Passo 2: Auditoria de Qualidade dos Dados
# ============================================
def audit_quality(df, name):
"""Executa auditoria de qualidade em um DataFrame"""
issues = []
# Valores faltantes
missing = df.isnull().sum()
if missing.sum() > 0:
issues.append(f"Faltantes: {dict(missing[missing > 0])}")
# Duplicatas
dups = df.duplicated().sum()
if dups > 0:
issues.append(f"Duplicatas: {dups}")
# Tipos
object_cols = df.select_dtypes(include='object').columns.tolist()
if object_cols:
issues.append(f"Colunas objeto: {object_cols}")
status = "⚠️ PROBLEMAS" if issues else "✅ LIMPO"
print(f"{name}: {status}")
for issue in issues:
print(f" - {issue}")
return issues
audit_quality(customers, 'Clientes')
audit_quality(products, 'Produtos')
audit_quality(orders, 'Pedidos')
audit_quality(regions, 'Regiões')
audit_quality(inv_df, 'Inventário')
# Injetar problemas para demo
orders.loc[np.random.choice(2000, 100, replace=False), 'discount'] = np.nan
dups = orders.sample(30)
orders = pd.concat([orders, dups], ignore_index=True)
print(f"\nApós injeção de problemas: formato dos pedidos = {orders.shape}")
> **Saída:** Execute em um ambiente Python local (pandas 2.x). O servidor Piston não tem pandas pré-instalado. Por favor, instale localmente (`pip install pandas`) e acompanhe. Os valores reais podem variar ligeiramente dependendo da sua versão do pandas.
5. Merge de 4 Tabelas + Limpeza
▶ Exemplo
> **Saída:** Execute em um ambiente Python local (pandas 2.x). O servidor Piston não tem pandas pré-instalado. Por favor, instale localmente (`pip install pandas`) e acompanhe. Os valores reais podem variar ligeiramente dependendo da sua versão do pandas.
: Merge complexo + limpeza com pipe (Dificuldade: 3/5 estrelas)
# ============================================
# Passo 3-4: Merge de 4 Tabelas + Limpeza
# ============================================
def clean_orders(df):
df = df.drop_duplicates(subset='order_id', keep='last')
df['discount'] = df['discount'].fillna(0)
return df
# Passo 1: Limpar pedidos
clean_orders_df = orders.pipe(clean_orders)
# Passo 2: Merge pedidos + produtos
op = pd.merge(clean_orders_df, products, on='product_id', how='left')
# Passo 3: Merge + clientes
opc = pd.merge(op, customers, on='customer_id', how='left')
# Passo 4: Merge + regiões
full = pd.merge(opc, regions, on='country', how='left')
# Passo 5: Merge + inventário
full = pd.merge(full, inv_df, on='product_id', how='left')
# Colunas derivadas
full['revenue'] = full['unit_price'] * full['quantity'] * (1 - full['discount'])
full['cost_estimate'] = full['unit_price'] * full['quantity'] * 0.6
full['profit'] = full['revenue'] - full['cost_estimate']
full['month'] = full['order_date'].dt.to_period('M')
full['is_low_stock'] = full['stock'] < full['reorder_level']
print(f"✅ Dataset completo: {full.shape}")
print(f"Colunas: {full.columns.tolist()}")
print(f"Faltantes: {full.isnull().sum().sum()}")
> **Saída:** Execute em um ambiente Python local (pandas 2.x). O servidor Piston não tem pandas pré-instalado. Por favor, instale localmente (`pip install pandas`) e acompanhe. Os valores reais podem variar ligeiramente dependendo da sua versão do pandas.
6. Groupby Multidimensional + Análise Pivô
▶ Exemplo
> **Saída:** Execute em um ambiente Python local (pandas 2.x). O servidor Piston não tem pandas pré-instalado. Por favor, instale localmente (`pip install pandas`) e acompanhe. Os valores reais podem variar ligeiramente dependendo da sua versão do pandas.
: Agregação multidimensional e análise cruzada (Dificuldade: 3/5 estrelas)
# ============================================
# Passo 5-6: Análise Multidimensional
# ============================================
# 1. Receita por região × categoria
region_cat = full.groupby(['region', 'category']).agg(
revenue=('revenue', 'sum'),
orders=('order_id', 'count'),
avg_order_value=('revenue', 'mean'),
profit_margin=('profit', lambda x: x.sum() / full.loc[x.index, 'revenue'].sum())
).round(2)
print("=== Receita por Região × Categoria ===")
print(region_cat.head(8))
# 2. Tendência mensal por região
monthly_region = full.groupby(['month', 'region'])['revenue'].sum().unstack()
print(f"\n=== Mensal por Região ===\n{monthly_region.tail(3)}")
# 3. Tabela pivô: segmento × categoria
seg_cat = pd.pivot_table(
full, values='revenue', index='segment', columns='category',
aggfunc='sum', margins=True, margins_name='Total'
).round(0)
print(f"\n=== Pivô Segmento × Categoria ===\n{seg_cat}")
# 4. Produtos top
top_products = full.groupby('product_name').agg(
revenue=('revenue', 'sum'),
quantity=('quantity', 'sum'),
avg_discount=('discount', 'mean')
).nlargest(5, 'revenue')
print(f"\n=== Top 5 Produtos ===\n{top_products}")
# 5. Alerta de estoque baixo
low_stock = full[full['is_low_stock']].groupby('product_name').agg(
stock=('stock', 'first'),
reorder_level=('reorder_level', 'first'),
total_orders=('order_id', 'count')
).sort_values('total_orders', ascending=False)
print(f"\n=== Alerta de Estoque Baixo ===\n{low_stock.head(5)}")
> **Saída:** Execute em um ambiente Python local (pandas 2.x). O servidor Piston não tem pandas pré-instalado. Por favor, instale localmente (`pip install pandas`) e acompanhe. Os valores reais podem variar ligeiramente dependendo da sua versão do pandas.
7. Relatório Styler e Exportação Multi-Sheet
▶ Exemplo
> **Saída:** Execute em um ambiente Python local (pandas 2.x). O servidor Piston não tem pandas pré-instalado. Por favor, instale localmente (`pip install pandas`) e acompanhe. Os valores reais podem variar ligeiramente dependendo da sua versão do pandas.
: Relatório Styler + exportação para Excel (Dificuldade: 3/5 estrelas)
# ============================================
# Passo 7: Relatório Estilizado + Exportação
# ============================================
# Estilizar a pivô segmento × categoria
styled_pivot = (seg_cat.style
.format('${:,.0f}')
.background_gradient(cmap='RdYlGn', axis=None)
.set_caption('Receita por Segmento × Categoria')
)
# Estilizar top produtos
styled_products = (top_products.style
.format({'revenue': '${:,.0f}', 'quantity': '{:,}', 'avg_discount': '{:.1%}'})
.bar(subset=['revenue'], color='lightblue')
.highlight_max(subset=['revenue'], color='lightgreen')
)
# Estilizar alerta de estoque baixo
styled_stock = (low_stock.head(10).style
.format({'stock': '{:.0f}', 'reorder_level': '{:.0f}', 'total_orders': '{:,}'})
.background_gradient(subset=['total_orders'], cmap='YlOrRd')
.set_caption('Alerta de Estoque Baixo — Produtos de Alta Demanda')
)
# Exportar para Excel com múltiplas folhas
output_path = 'ecommerce_report.xlsx'
with pd.ExcelWriter(output_path, engine='openpyxl') as writer:
# Folha de resumo
summary = pd.DataFrame({
'Métrica': ['Receita Total', 'Lucro Total', 'Total de Pedidos',
'Clientes Únicos', 'Produtos Únicos', 'Valor Médio do Pedido',
'Margem de Lucro'],
'Valor': [full['revenue'].sum(), full['profit'].sum(), len(full),
full['customer_id'].nunique(), full['product_id'].nunique(),
full['revenue'].mean(), full['profit'].sum() / full['revenue'].sum()]
})
summary.to_excel(writer, sheet_name='Resumo', index=False)
# Região × Categoria
region_cat.to_excel(writer, sheet_name='Região-Categoria')
# Tendência mensal
monthly_region.to_excel(writer, sheet_name='Tendência-Mensal')
# Segmento × Categoria (estilizado)
styled_pivot.to_excel(writer, sheet_name='Segmento-Categoria')
# Produtos Top
top_products.to_excel(writer, sheet_name='Top-Produtos')
print(f"✅ Relatório exportado: {output_path}")
# Resumo final
print("\n" + "=" * 50)
print(" ANÁLISE ABRANGENTE DE E-COMMERCE COMPLETA")
print("=" * 50)
print(f" Receita: ${full['revenue'].sum():,.0f}")
print(f" Lucro: ${full['profit'].sum():,.0f}")
print(f" Margem: {full['profit'].sum() / full['revenue'].sum():.1%}")
print(f" Região Top: {full.groupby('region')['revenue'].sum().idxmax()}")
print(f" Categoria Top: {full.groupby('category')['revenue'].sum().idxmax()}")
print(f" Itens com Estoque Baixo: {len(low_stock)}")
> **Saída:** Execute em um ambiente Python local (pandas 2.x). O servidor Piston não tem pandas pré-instalado. Por favor, instale localmente (`pip install pandas`) e acompanhe. Os valores reais podem variar ligeiramente dependendo da sua versão do pandas.
❓ Perguntas Frequentes
P: Como você unifica formatos em múltiplas fontes de dados? R: Padronize em três passos: (1) Normalize nomes de colunas -- use o mesmo nome para a mesma chave (ex: customer_id em todos os lugares); (2) Unifique tipos -- converta todas as colunas de data com to_datetime e todas as colunas de ID para int; (3) Unifique codificação -- prefira UTF-8, e converta GBK para UTF-8. Antes do mesclagem, verifique o dtype e os valores únicos das colunas-chave para confirmar que podem corresponder.
P: Como você quantifica a qualidade dos dados? R: Avalie quatro dimensões: (1) Completude (taxa de faltantes = contagem faltante / contagem total, meta < 5%); (2) Consistência (as colunas-chave têm correspondências nas tabelas relacionadas?); (3) Precisão (proporção de outliers, ex: valores negativos ou extremos); (4) Atualidade (quando os dados foram atualizados pela última vez -- estão desatualizados?). Dê uma pontuação de 1 a 5 para cada dimensão para uma avaliação geral.
P: E se a cadeia de merges ficar muito longa? R: Mescle passo a passo e valide após cada junção -- verifique a contagem de linhas e valores faltantes a cada vez. Para um mesclagem de 5 tabelas, não escreva tudo de uma vez. Divida em 4 passos: pedidos+produtos -> +clientes -> +regiões -> +inventário. Após cada passo, print(formato, faltantes) para confirmar a correção antes de prosseguir.
P: Como você automatiza relatórios? R: Use ExcelWriter para produzir múltiplas folhas (resumo + análise por dimensão + pivôs estilizados), ou use Styler.to_html() para gerar um relatório baseado na web. Indo além: use Jupyter Notebook + nbconvert para gerar PDFs automaticamente. A abordagem final: parametrize notebooks com papermill e execute-os em agendamento para produzir relatórios automaticamente.
P: Como isso se compara a ferramentas de BI? R: Pandas é excelente para análises flexíveis e personalizadas -- não é limitado pelos recursos integrados de uma ferramenta de BI, e você pode implementar lógica arbitrariamente complexa. Ferramentas de BI (Tableau/Power BI) são mais adequadas para dashboards padronizados e exploração interativa -- a criação de gráficos por arrastar e soltar é rápida, mas cálculos complexos são restritos. Estratégia: use Pandas para análise profunda e preparação de dados, depois use ferramentas de BI para apresentação visual.
P: Como você constrói tabelas pivô multidimensionais? R: Passe múltiplas colunas para o índice:
pd.pivot_table(df, index=['região','segmento'], columns='categoria'), o que produz colunas MultiIndex. Defina margins=True para adicionar totais de linha e coluna. Análise cruzada significa uma dimensão como linhas, uma como colunas e uma como valores -- esta é a maneira mais intuitiva de exibir dados tridimensionais.
P: Como você implementa alertas de estoque baixo? R: Compare o estoque com o reorder_level --
df[df['stock'] < df['reorder_level']]. Para priorizar, ordene por volume de pedidos: estoque baixo + alto volume de pedidos = mais urgente. Use o background_gradient do Styler para indicar o nível de urgência, com vermelho significando "reabastecer imediatamente".
📖 Resumo
- Carregamento multi-fonte: pd.read_csv/read_excel/read_sql com nomes e tipos de chave unificados
- Auditoria de qualidade: avalie completude, consistência, precisão e atualidade em quatro dimensões
- Validação de mesclagem passo a passo: verifique a contagem de linhas e valores faltantes após cada mesclagem
- Groupby multidimensional: região x categoria, segmento x categoria, mês x região
- Análise cruzada pivot_table: índice = dimensão de linha, colunas = dimensão de coluna, margins=True
- Relatórios Styler: encadeie formatação + gradiente + barra + destaque para uma estilização polida
- Exportação multi-sheet com ExcelWriter: resumo + análise por dimensão + tabelas estilizadas
📝 Exercícios
- Básico (Dificuldade: 1/5 estrelas): Crie 2 DataFrames (clientes + pedidos), mescle-os, calcule as vendas totais por região e use o parâmetro indicator para verificar a cobertura da correspondência.
- Intermediário (Dificuldade: 2/5 estrelas): Simule 3 fontes de dados (clientes/produtos/pedidos), realize 3 merges -> limpeza -> agregação groupby multidimensional -> tabulação cruzada pivot_table -> formatação Styler.
- Desafio (Dificuldade: 3/5 estrelas): Complete o projeto completo desta lição: carregue 5 fontes -> auditoria de qualidade -> mesclagem de 4 tabelas -> limpeza com pipe -> groupby multidimensional + pivô -> relatório Styler -> exportação multi-sheet com ExcelWriter.
<- Lição Anterior: Projeto - Séries Temporais | Conclusão do Curso ->