Aula 06
Python para Dados
Um único projeto de vendas para entender como cada biblioteca resolve uma etapa real.
Extrair
Arquivos e APIs.
Tratar
DataFrames e regras.
Entregar
Banco e dashboard.
Escalar
Orquestração, Spark e ML.
O caso da aula
Três arquivos contam uma única história de vendas
clientes.csv
cliente_id
nome
estado
segmento
email
vendas.csv
venda_id
data
cliente_id
produto_id
quantidade
produtos.csv
produto_id
produto
categoria
preco
custo
Ao final
Você saberá escolher a ferramenta pela etapa do fluxo
Ler e transformar
CSV, filtros, colunas, grupos, ordenação e junções.
Confiar nos dados
Caminhos portáveis, segredos protegidos e contratos validados.
Persistir e integrar
Banco de dados e APIs sem perder a estrutura tabular.
Entregar valor
Dashboard simples e reproduzível.
Operar em produção
Agendamento, monitoramento e tentativas automáticas.
Escalar e prever
Cluster e primeiro contato com machine learning.
Origem
Python nasceu simples e cresceu com a comunidade
Guido van Rossum cria Python no CWI, na Holanda.
As primeiras versões públicas aparecem.
A Python Software Foundation é formada.
Open source, multiplataforma e presente em dados, web, automação e IA.
Código legível reduziu a distância entre uma pergunta e um resultado executável.
Fonte: documentação oficial do Python, “History and License”.
Mercado
Python combina adoção ampla com uma carreira que exige contexto
dos respondentes do Stack Overflow 2025 usaram Python.
de crescimento de adoção entre 2024 e 2025.
salário-base médio informado para Analista de Dados no Brasil.
O número não é promessa
Salário varia por cidade, senioridade, setor, idioma e responsabilidade. Python aumenta repertório; não substitui SQL, negócio e comunicação.
O diferencial
Conseguir automatizar uma análise, validar a origem e entregar um resultado reproduzível.
Fontes: Stack Overflow Developer Survey 2025; Indeed Brasil, atualização de 12/07/2026, 1,6 mil salários informados.
Ecossistema
Uma linguagem conecta áreas que antes viviam separadas
Aprendizado
Sintaxe direta e feedback rápido.
Bibliotecas
Pacotes especializados no PyPI.
Integração
Arquivos, bancos, APIs, nuvem e BI.
Comunidade
Documentação, eventos e código aberto.
Casos reais
Python.org reúne histórias em finanças, manufatura, aviação, ciência, governo e software. Bluevine descreve Python em backend, engenharia, ciência e análise de dados.
O ponto principal
Não existe “biblioteca vencedora” para tudo. Existe uma caixa de ferramentas coerente para problemas diferentes.
Mapa da aula
Do arquivo ao modelo, cada biblioteca tem um papel
Pandas · Polars
Manipular tabelas.
Pathlib · dotenv
Organizar e proteger.
Pydantic
Validar contratos.
SQLAlchemy
Persistir em banco.
Requests
Consumir APIs.
Streamlit
Entregar interface.
Prefect · Airflow
Orquestrar fluxos.
PySpark · sklearn
Escalar e prever.
Onde Python entra
Python pode participar de todas as etapas sem fazer tudo sozinho
CSV, banco ou API.
Requests, Pandas.
Pandas, Polars.
Pydantic.
SQLAlchemy.
Streamlit.
Prefect, Airflow.
Spark, sklearn.
Ambiente
Um ambiente virtual mantém o projeto reproduzível
Estrutura mínima
aula06/
├─ dados/
├─ exemplos/
├─ projeto_bcb/
├─ saida/
├─ .venv/
└─ requirements.txt
# cria um ambiente isolado python -m venv .venv # se o PowerShell bloquear, execute uma vez Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser # ativa e instala as dependências .venv\Scripts\Activate.ps1 python -m pip install -r requirements.txt
Erro comum · ativação bloqueada
Depois da política RemoteSigned, reabra o terminal, confirme python --version e selecione o interpretador da pasta .venv no VS Code.
Jupyter
Um notebook alterna explicação, código e resultado
Célula Markdown
Qual categoria gera mais receita?
Registra hipótese, raciocínio e conclusão.
Célula de código
# executa no kernel ativo
vendas.groupby("categoria")[
"valor_total"
].sum()O resultado aparece logo abaixo da célula.
Kernel
Processo que mantém variáveis em memória.
Execução
A ordem real importa mais que a posição visual.
Restart
Reiniciar e executar tudo testa reprodutibilidade.
Comparação
Escolha o ambiente pelo tipo de trabalho
Pandas · problema
CSV não responde perguntas até ganhar estrutura
Uma tabela com linhas, colunas, índice e tipos.
Pandas · anatomia do código
Ler, selecionar e filtrar são três decisões diferentes
# importa a biblioteca import pandas as pd # lê o CSV e interpreta a data vendas = pd.read_csv( "dados/vendas.csv", parse_dates=["data"] ) # seleciona duas colunas recorte = vendas[ ["produto_id", "quantidade"] ]
# cria uma condição booleana concluida = ( vendas["status"] == "Concluida" ) # filtra e cria uma cópia segura resultado = vendas.loc[ concluida ].copy() # calcula o valor de cada linha resultado["valor_total"] = ( resultado["quantidade"] * resultado["preco_unitario"] )
Pandas · pergunta de negócio
Qual categoria gera mais receita?
Raciocínio
categoria
somar receita
maior primeiro
# agrupa linhas da mesma categoria resumo = ( base.groupby( "categoria", as_index=False ) # calcula duas medidas .agg( receita=("valor_total", "sum"), itens=("quantidade", "sum") ) # ordena pela maior receita .sort_values( "receita", ascending=False ) )
Pandas · enriquecimento
Merge conecta chaves para devolver contexto
vendas
cliente_id
produto_id
quantidade
merge
on="cliente_id"
how="left"
on="produto_id"
base completa
nome
estado
produto
categoria
# preserva todas as vendas e acrescenta dimensões base = vendas.merge(clientes, on="cliente_id", how="left").merge(produtos, on="produto_id", how="left") # exporta sem criar uma coluna de índice base.to_csv("saida/vendas_tratadas.csv", index=False)
Pandas · demonstração
Leia o erro como uma pista sobre a etapa que falhou
FileNotFoundError
O arquivo não está no caminho esperado. Confirme a pasta com Path.cwd().
KeyError
A coluna não existe ou contém espaços. Veja df.columns.
TypeError
Uma coluna possui tipo inesperado. Inspecione df.dtypes.
Mercado · ★★★★★
Aprenda primeiro. É a referência de manipulação tabular em análise, notebooks, automações e preparação para BI.
Demo ao vivo
Execute 01_pandas.py, compare o resumo e abra saida/resumo_pandas.csv.
Polars · problema
Quando o volume cresce, o motor do DataFrame importa
Em geral, cada instrução produz um resultado imediato.
Pode observar o plano completo e otimizar antes de executar.
Polars · anatomia do código
Expressões descrevem o resultado; collect executa o plano
# importa o Polars import polars as pl # scan_csv cria um plano lazy sem carregar tudo imediatamente resumo = ( pl.scan_csv("dados/vendas.csv") # aplica o filtro o mais cedo possível .filter(pl.col("status") == "Concluida") # calcula a receita de cada linha .with_columns((pl.col("quantidade") * pl.col("preco_unitario")).alias("valor_total")) # agrega e ordena .group_by("produto_id").agg(pl.col("valor_total").sum().alias("receita")) .sort("receita", descending=True) # executa o plano otimizado .collect() )
A API lazy pode aplicar predicate pushdown, projection pushdown e outras otimizações antes da materialização.
Polars · performance
Benchmark é medição, não slogan
Como medir
# inicia o cronômetro inicio = perf_counter() # executa a transformação resultado = consulta.collect() # calcula o tempo decorrido tempo = perf_counter() - inicio
Mercado · ★★★★☆
Ótimo segundo passo quando o processamento local precisa de mais velocidade ou menos memória.
Erros comuns
ColumnNotFoundError: confira o schema. SchemaError: normalize tipos. Resultado “instantâneo” sem collect() ainda é apenas um plano lazy.
Pathlib · caminhos
Barra invertida não deveria decidir onde seu código roda
# depende do computador e do sistema
caminho = "C:\\curso\\dados\\vendas.csv"Pasta fixa, separador manual e pouca informação sobre o arquivo.
# parte da localização do próprio script raiz = Path(__file__).resolve().parent.parent # monta o caminho correto no sistema atual arquivo = raiz / "dados" / "vendas.csv"
Mercado · ★★★★★
Biblioteca padrão. Use em qualquer projeto que leia ou grave arquivos.
Erro comum
Path.cwd() é a pasta de onde o comando foi iniciado; __file__ aponta para o script.
dotenv · segurança
Senha no código vira incidente quando o arquivo é compartilhado
# arquivo .env — somente no computador DATABASE_URL=postgresql://usuario:senha@servidor/vendas API_TOKEN=segredo-local # arquivo .env.example — pode ser compartilhado DATABASE_URL= API_TOKEN=
# carrega as variáveis do arquivo .env from dotenv import load_dotenv load_dotenv() # lê a configuração sem expor o valor import os url = os.getenv("DATABASE_URL") # falha cedo se estiver ausente if not url: raise RuntimeError("DATABASE_URL ausente")
Mercado · ★★★★☆
Comum no desenvolvimento local. Em produção, prefira o gerenciador de segredos da plataforma.
Erros comuns
Subir .env para o Git; esquecer load_dotenv(); misturar configuração de teste e produção.
Pydantic · problema
Um arquivo pode abrir e ainda conter dados inválidos
idade
"dezesseis"
esperado: inteiro ≥ 18
"ana@dominio"
esperado: endereço válido
cpf
"123"
esperado: 11 dígitos
dict, JSON ou linha.
Tipos e regras.
Aceitar ou rejeitar.
Dado confiável.
Pydantic · código comentado
O modelo transforma regra de negócio em validação executável
# importa tipos de validação from pydantic import ( BaseModel, Field, field_validator ) class Cliente(BaseModel): # converte texto numérico para inteiro idade: int = Field(ge=18) email: str = Field( pattern=r"^[^@]+@[^@]+\.[^@]+$" ) cpf: str @field_validator("cpf") @classmethod def validar_cpf(cls, valor): # mantém somente números digitos = "".join( c for c in valor if c.isdigit() ) if len(digitos) != 11: raise ValueError("CPF inválido") return digitos
Resultado
Dados válidos seguem para o banco. Registros inválidos produzem erros por campo e podem ir para uma área de quarentena.
Mercado · ★★★★☆
Muito usado em APIs, serviços de dados, configurações e contratos entre sistemas.
Erros comuns
Confiar apenas em conversão automática; validar tarde demais; esconder o motivo da rejeição.
SQLAlchemy · persistência
O DataFrame precisa de uma ponte segura até o banco
Python
regra do fluxo
Engine
conexão SQLAlchemy
PostgreSQL
persistência real
SQL
consulta no banco
DataFrame
resultado tabular
BI
consumo final
Sem configuração
O exemplo usa SQLite porque não exige servidor e funciona imediatamente.
Com DATABASE_URL
O mesmo arquivo conecta ao PostgreSQL, MySQL ou SQL Server com o driver correspondente.
SQLAlchemy · código comentado
Uma engine centraliza como o Python conversa com o banco
# lê a URL do .env; vazio mantém SQLite import os from dotenv import load_dotenv from sqlalchemy import create_engine load_dotenv(".env") url = os.getenv("DATABASE_URL") or ( "sqlite:///saida/vendas.db" ) engine = create_engine(url) # grava em uma tabela exclusiva da aula vendas.to_sql( "vendas_aula06", engine, if_exists="replace", index=False )
# define uma consulta SQL explícita from sqlalchemy import text consulta = text(""" SELECT canal, SUM(quantidade) AS itens FROM vendas GROUP BY canal """) # lê o resultado como DataFrame resumo = pd.read_sql( consulta, engine )
Mercado · ★★★★☆
Base de muitas integrações Python com bancos. Aprenda engine, transação e SQL parametrizado.
Erros comuns
Driver ausente; URL incorreta; conexão não fechada; usar replace em produção sem intenção.
Requests · APIs
Nem toda fonte chega em CSV: muitas chegam por HTTP
Endereço do recurso.
Solicitação HTTP.
200, 404, 500...
Objetos e listas.
Tabela normalizada.
API pública
JSONPlaceholder fornece dados de teste para a demonstração.
Fallback local
api.json mantém o exemplo funcional sem internet.
Requests · código comentado
Timeout e raise_for_status evitam silêncios perigosos
# importa cliente HTTP e Pandas import requests import pandas as pd try: # limita o tempo de espera resposta = requests.get( "https://jsonplaceholder.typicode.com/users", timeout=10 ) # transforma 4xx e 5xx em erro resposta.raise_for_status() dados = resposta.json() except requests.RequestException: # usa cópia local sem internet dados = pd.read_json( "dados/api.json" ).to_dict("records") # abre campos aninhados usuarios = pd.json_normalize(dados)
Mercado · ★★★★★
Essencial para integrações simples. Em pipelines reais, acrescente autenticação, paginação, retry e logs.
Erros comuns
Sem timeout; ignorar status; token exposto; assumir que todos os objetos possuem os mesmos campos.
Streamlit · evolução
O mesmo dado pode evoluir de saída técnica para interface
Texto no terminal.
Tabela tratada.
Tabela interativa.
Comparação visual.
Filtro + KPI + ação.
Bom para
Protótipos, ferramentas internas, portfólios, exploração compartilhada e pequenos produtos de dados.
Atenção
Um dashboard não corrige dados ruins. Ele torna a qualidade — ou a falta dela — mais visível.
Streamlit · código comentado
Com poucas chamadas, o script vira uma aplicação local
# importa interface e dados import streamlit as st import pandas as pd # lê o mesmo CSV da aula vendas = pd.read_csv( "dados/vendas.csv" ) # cria um filtro lateral canal = st.sidebar.selectbox( "Canal", ["Todos", *sorted(vendas["canal"].unique())] ) # mostra tabela e gráfico st.dataframe(vendas) st.bar_chart( vendas.groupby("canal")[ "quantidade" ].sum() )
Execute
streamlit run exemplos/08_streamlit.py
Mercado · ★★★★☆
Excelente para demonstrar valor rapidamente; avalie autenticação e arquitetura antes de produção crítica.
Erros comuns
Rodar com python em vez de streamlit run; recalcular tudo a cada clique; não usar cache.
Prefect · fluxo observável
Um pipeline precisa explicar o que aconteceu quando falha
# transforma funções em tarefas observáveis from prefect import flow, task @task(retries=2, retry_delay_seconds=2) def extrair(): # uma falha transitória pode ser repetida return pd.read_csv("dados/vendas.csv") @flow(name="pipeline-vendas") def pipeline(): # estados e duração ficam registrados dados = extrair() transformar(dados) pipeline()
O que o fluxo ganha
- Pipeline: funções rastreáveis.
- Retry: novas tentativas.
- Monitoramento: estados, tempo e logs.
Mercado · ★★★☆☆
Boa escolha para equipes Python que querem adotar orquestração gradualmente.
Erro comum
Uma única task torna o retry caro e o erro pouco localizado.
Prefect · interface local
A execução vira uma linha do tempo que a equipe consegue investigar
1. Inicie a interface
prefect server start2. Conecte o cliente
prefect config set PREFECT_API_URL="http://127.0.0.1:4200/api"3. Execute e acompanhe
python exemplos/09_prefect.pyAbra 127.0.0.1:4200 e mostre tarefas, duração, estados e logs.
Airflow · DAG
Dependências formam um grafo que o scheduler acompanha
decide quando uma execução nasce
define tarefas e dependências
envia tarefas prontas para execução
# API do Airflow 3
from airflow.sdk import dag, task
@dag(
schedule="@daily",
start_date=datetime(2026, 1, 1),
catchup=False
)
def pipeline_vendas():
@task
def extrair():
return "vendas.csv"
@task
def transformar(arquivo):
return "vendas_tratadas.csv"
@task
def carregar(arquivo):
print(arquivo)
carregar(transformar(extrair()))
dag = pipeline_vendas()Mercado · ★★★★☆
Muito presente em plataformas de dados maduras, com várias DAGs, equipes e integrações.
Erros comuns
Confundir data lógica com horário de execução; criar DAG cíclica; fazer trabalho pesado ao importar o arquivo.
Comparação
Prefect e Airflow resolvem orquestração com experiências diferentes
PySpark · limite local
Quando um computador deixa de ser suficiente, distribua o trabalho
Memória
A base não cabe com segurança em uma máquina.
Tempo
O processamento local não termina na janela disponível.
Infraestrutura
Os dados já vivem em um lake e um cluster está disponível.
PySpark · arquitetura
O driver coordena; os executors processam partições
Driver
Cria o plano e distribui tarefas.
Cluster manager
Aloca CPU e memória para a aplicação.
Executor A
Processa partições 1 e 2.
Executor B
Processa partições 3 e 4.
Partição
Fatia do conjunto de dados.
Task
Unidade enviada ao executor.
Shuffle
Movimento de dados entre partições; pode custar caro.
Fonte conceitual: Apache Spark Cluster Mode Overview.
PySpark · código comentado
A intenção é parecida; a execução ocorre em um cluster
# lê localmente vendas = pd.read_csv( "dados/vendas.csv" ) # agrega em memória resumo = ( vendas.groupby("canal")[ "quantidade" ].sum() )
# cria a sessão Spark spark = SparkSession.builder.getOrCreate() # lê e distribui o DataFrame vendas = spark.read.csv( "dados/vendas.csv", header=True, inferSchema=True ) # cria um plano distribuído resumo = vendas.groupBy("canal").sum( "quantidade" ) resumo.show()
Mercado · ★★★★☆
Relevante em engenharia de dados, lakes e grandes volumes. Aprenda depois de SQL e DataFrames locais.
Avisos no Windows
winutils.exe e native-hadoop são informativos nesta leitura local. O aviso do pandas desaparece com pandas<3. Falhas reais: Java ausente, JAVA_HOME incorreto, excesso de shuffle ou uso indiscriminado de toPandas().
Scikit-learn · primeiro modelo
Machine learning aprende uma relação para estimar novos casos
linhas históricas
X: quantidade e preço
fit(X, y)
relação aprendida
predict(novo X)
Treino
Exemplos usados para ajustar o modelo.
Teste
Exemplos separados para medir se o modelo generaliza.
Scikit-learn · código comentado
Separar treino e teste evita avaliar o modelo com a própria prova
# escolhe características e alvo X = vendas[[ "quantidade", "preco_unitario" ]] y = vendas["valor_total"] # reserva 25% para avaliação X_treino, X_teste, y_treino, y_teste = ( train_test_split( X, y, test_size=0.25, random_state=42 ) ) # aprende com o treino modelo = LinearRegression() modelo.fit(X_treino, y_treino) # prevê e mede o erro no teste previsoes = modelo.predict(X_teste) erro = mean_absolute_error( y_teste, previsoes )
Mercado · ★★★☆☆
Base sólida para ML clássico. Aprenda depois de dominar limpeza, variáveis e avaliação.
Erros comuns
Vazamento entre treino e teste; base pequena; alvo mal definido; comemorar acurácia sem referência.
Escopo da aula
Entender o fluxo fit → predict → avaliar, sem aprofundar algoritmos.
Decisão
Escolha a biblioteca pelo problema observável
Projeto final
Do CSV ao dashboard com validação no meio
CSV
clientes, produtos e vendas
Pandas
filtro, cálculo e merge
Pydantic
contrato por registro
SQLAlchemy
tabela fato_vendas
Streamlit
filtro, KPI e gráfico
Decisão
receita por região e categoria
Entrada controlada
Pathlib encontra arquivos; dotenv protege configurações.
Fluxo observável
Prefect ou Airflow agenda, registra e repete.
Evolução
Spark entra quando a escala local deixa de atender.
Projeto final
O esqueleto combina extração, qualidade e persistência
# 1. encontra as fontes do projeto ROOT = Path(__file__).resolve().parent.parent vendas = pd.read_csv(ROOT / "dados" / "vendas.csv") # 2. valida cada registro antes do tratamento validas = [] for registro in vendas.to_dict("records"): try: Venda.model_validate(registro) validas.append(registro) except ValidationError as erro: print("Registro rejeitado:", erro.error_count()) # 3. transforma e calcula a receita base = pd.DataFrame(validas) base = base.loc[base["status"] == "Concluida"].copy() base["valor_total"] = base["quantidade"] * base["preco_unitario"] # 4. grava a camada analítica no banco engine = create_engine("sqlite:///saida/projeto_final.db") base.to_sql("fato_vendas", engine, if_exists="replace", index=False)
Onde as demais ferramentas entram
O projeto cresce substituindo capacidades, não reescrevendo a história
Requests
Troca o CSV externo por uma API paginada.
Polars
Acelera transformações locais maiores.
Prefect
Adiciona estados, retry e agenda com pouco atrito.
Airflow
Organiza muitas DAGs e dependências de plataforma.
Spark
Distribui volume que excede uma máquina.
Scikit-learn
Acrescenta previsão depois que a base é confiável.
Power BI
Entrega análise governada a mais públicos.
Testes
Protegem regras antes de cada publicação.
Demonstração para chamar atenção
O Radar Econômico conecta fonte oficial, previsão e operação visível
BCB SGS
câmbio e Meta Selic
Prefect
retry, estados e logs
Pandas
tipos, lags e média móvel
sklearn
regressão e MAE
SQLAlchemy
camada analítica SQLite
Streamlit
KPI, série e projeção
1. Mostre a fonte
A API do Banco Central entrega dados oficiais; uma amostra versionada mantém a aula offline.
2. Provoque a pergunta
“Como transformar uma cotação em um processo confiável, observável e reutilizável?”
3. Revele o fluxo
Execute o Prefect, acompanhe as tasks e termine no dashboard com o próximo ponto estimado.
Exercício
Construa uma análise de vendas reproduzível
Trabalho em dupla · 30 minutosvendas.csv
somente concluídas
valor_total
receita por canal
resumo.csv
Streamlit
Obrigatório
Pathlib, comentários, tratamento de status e saída sem índice.
Bônus
Filtro por canal, ticket médio e validação de quantidade positiva.
Entrega
Script + CSV gerado + captura do dashboard.
Solução esperada
O código está pronto quando outra pessoa consegue reproduzir
Correto
Vendas canceladas não entram na receita.
Legível
Nomes e comentários explicam a intenção.
Portátil
Nenhum caminho depende do seu computador.
Seguro
Nenhuma senha aparece no arquivo.
Observável
Erros informam arquivo, coluna ou regra.
Repetível
Executar novamente produz o mesmo resultado.
Reprodução
Tudo que apareceu na aula está no pacote da Aula 06
aula06/
├─ aula-06-python-para-dados.html
├─ python-3.12.7-amd64.exe
├─ dados/ · 3 CSVs + JSON
├─ exemplos/ · 13 scripts
├─ projeto_bcb/ · pipeline + dashboard
├─ requirements.txt
├─ .env.example
└─ README.md
1. Instale
Crie .venv e instale requirements.
2. Execute
Comece por 01_pandas.py.
3. Compare
Rode o mesmo fluxo em Polars e Spark.
4. Entregue
Abra o dashboard Streamlit.
Fechamento
Python conecta o fluxo; seu raciocínio escolhe as peças
Comece com dados pequenos, contratos claros e um resultado reproduzível. Escale somente quando o problema exigir.