Objetivos de Aprendizagem
Ao concluir este tutorial, você será capaz de:
- Usar o pandas para ler dados de arquivos de texto como CSV e TSV.
- Ler arquivos Excel e gerenciar múltiplas planilhas.
- Lidar com problemas comuns de codificação e formatos de dados anômalos.
- Utilizar a leitura em partes (chunking) para processar arquivos maiores que a memória disponível.
- Conectar-se a bancos de dados SQLite e MySQL para executar consultas.
- Aplicar técnicas de otimização de desempenho na leitura de dados.
Introdução ao Pandas
O pandas é uma biblioteca fundamental para análise de dados em Python, construída sobre o NumPy. Suas duas estruturas de dados centrais são:
- Series: Um array unidimensional com rótulos.
- DataFrame: Uma tabela bidimensional, similar a uma planilha do Excel.
import pandas as pd
import numpy as np
# Exemplo de Series
notas = pd.Series([85, 92, 78, 96],
index=['Ana', 'Bruno', 'Carlos', 'Diana'],
name='Matemática')
print(notas)
# Exemplo de DataFrame
tabela_funcionarios = pd.DataFrame({
'Nome': ['Ana', 'Bruno', 'Carlos', 'Diana'],
'Departamento': ['TI', 'Marketing', 'Financeiro', 'TI'],
'Salario': [15000, 12000, 13000, 18000]
})
print(tabela_funcionarios)
Leitura de Arquivos CSV
Leitura Básica
O formato CSV (valores separados por vírgula) é o formato de troca de dados mais comum.
# Criar um arquivo CSV de exemplo
dados_pedidos = {
'PedidoID': range(1, 6),
'Produto': ['Notebook', 'Monitor', 'Teclado', 'Mouse', 'Webcam'],
'Preco': [3500, 1200, 250, 150, 300],
'Quantidade': [1, 2, 3, 5, 2]
}
df_pedidos = pd.DataFrame(dados_pedidos)
df_pedidos.to_csv('exemplo_pedidos.csv', index=False, encoding='utf-8')
# Ler o arquivo CSV
df_lido = pd.read_csv('exemplo_pedidos.csv')
print(f"Formato dos dados: {df_lido.shape}")
print(df_lido.dtypes)
Parâmetros Comuns do read_csv
# Demonstração de parâmetros úteis
# Criar um CSV mais complexo
csv_complexo = """ID,Nome,Nota,Status
001,Lucas,85.5,Aprovado
002,Maria,,Pendente
003,João,92.0,Aprovado
004,Ana,abc,Reprovado"""
with open('dados_complexos.csv', 'w', encoding='utf-8') as f:
f.write(csv_complexo)
# 1. Especificar nomes das colunas
print("1. Colunas renomeadas:")
df_custom = pd.read_csv('dados_complexos.csv',
names=['Identificador', 'Aluno', 'Pontuacao', 'Situacao'],
header=0)
print(df_custom)
# 2. Ler apenas colunas específicas
print("\n2. Apenas Nome e Nota:")
df_parcial = pd.read_csv('dados_complexos.csv', usecols=['Nome', 'Nota'])
print(df_parcial)
# 3. Lidar com valores faltantes
print("\n3. Análise de dados faltantes:")
df_completo = pd.read_csv('dados_complexos.csv', na_values=['', ' '])
print(df_completo.isna().sum())
# 4. Definir tipos de dados específicos
print("\n4. Tipos de dados definidos:")
df_tipado = pd.read_csv('exemplo_pedidos.csv',
dtype={'PedidoID': str, 'Produto': 'category'})
print(df_tipado.dtypes)
# 5. Ler apenas primeiras N linhas (para pré-visualização)
print("\n5. Primeiras 3 linhas:")
df_amostra = pd.read_csv('exemplo_pedidos.csv', nrows=3)
print(df_amostra)
Arquivos com Outros Delimitadores
# Arquivo TSV (separado por tabulação)
dados_tsv = "ID\tNome\tNota\n1\tLucas\t85\n2\tMaria\t92"
with open('dados.tsv', 'w', encoding='utf-8') as f:
f.write(dados_tsv)
print("Leitura de TSV:")
df_tsv = pd.read_csv('dados.tsv', sep='\t')
print(df_tsv)
# Arquivo separado por ponto e vírgula (comum em locais europeus)
dados_ptv = "ID;Nome;Nota\n1;Lucas;85\n2;Maria;92"
with open('dados_ptv.csv', 'w', encoding='utf-8') as f:
f.write(dados_ptv)
print("\nLeitura com delimitador ';':")
df_ptv = pd.read_csv('dados_ptv.csv', sep=';')
print(df_ptv)
Leitura de Arquivos Excel
Leitura Básica
# Criar um arquivo Excel de exemplo
df_vendas = pd.DataFrame({
'Vendedor': ['Ana', 'Bruno', 'Carlos'],
'Região': ['Norte', 'Sul', 'Leste'],
'Vendas_Q1': [45000, 32000, 28000],
'Vendas_Q2': [48000, 35000, 31000]
})
df_estoque = pd.DataFrame({
'Produto': ['P1', 'P2', 'P3'],
'Quantidade': [150, 230, 180],
'Preco_Unitario': [50.0, 75.0, 30.0]
})
# Salvar em diferentes planilhas
with pd.ExcelWriter('dados_empresariais.xlsx', engine='openpyxl') as escritor:
df_vendas.to_excel(escritor, sheet_name='Vendas', index=False)
df_estoque.to_excel(escritor, sheet_name='Estoque', index=False)
# Ler uma planilha específica
print("Planilha de Vendas:")
df_vendas_lido = pd.read_excel('dados_empresariais.xlsx', sheet_name='Vendas')
print(df_vendas_lido)
# Listar todas as planilhas
arquivo_excel = pd.ExcelFile('dados_empresariais.xlsx')
print(f"\nPlanilhas disponíveis: {arquivo_excel.sheet_names}")
# Ler todas as planilhas
todas_planilhas = pd.read_excel('dados_empresariais.xlsx', sheet_name=None)
for nome, df in todas_planilhas.items():
print(f"\n--- {nome} ---")
print(df.head(2))
Resolvendo Problemas de Codificação
Erros de codificação são frequentes ao trabalhar com dados reais. O erro UnicodeDecodeError indica que o arquivo não está sendo lido com a codificação correta.
# Função para detectar e lidar com codificações
import chardet
def detectar_codificacao(caminho_arquivo):
with open(caminho_arquivo, 'rb') as f:
resultado = chardet.detect(f.read(10000))
return resultado['encoding']
def ler_csv_seguro(caminho_arquivo):
codificacoes_tentar = ['utf-8', 'utf-8-sig', 'latin-1', 'gbk']
for cod in codificacoes_tentar:
try:
df = pd.read_csv(caminho_arquivo, encoding=cod)
print(f"Arquivo lido com sucesso usando codificação: {cod}")
return df
except UnicodeDecodeError:
continue
raise ValueError("Não foi possível ler o arquivo com as codificações conhecidas.")
# Exemplo de uso
# codificacao_detectada = detectar_codificacao('meu_arquivo.csv')
# df = ler_csv_seguro('meu_arquivo.csv')
Leitura em Partes para Arquivos Grandes
Para arquivos que excedem a memória disponível, use o parâmetro chunksize para processar em partes.
# Criar um arquivo grande para demonstração
np.random.seed(42)
num_linhas = 50000
df_grande = pd.DataFrame({
'ID': range(num_linhas),
'Valor': np.random.normal(100, 25, num_linhas),
'Categoria': np.random.choice(['Alpha', 'Beta', 'Gamma'], num_linhas)
})
df_grande.to_csv('arquivo_grande.csv', index=False)
# Processar em partes
tamanho_chunk = 10000
contagem_categorias = {}
soma_valores = 0.0
total_linhas = 0
for chunk in pd.read_csv('arquivo_grande.csv', chunksize=tamanho_chunk):
# Contar categorias
contagem = chunk['Categoria'].value_counts()
for cat, cont in contagem.items():
contagem_categorias[cat] = contagem_categorias.get(cat, 0) + cont
# Somar valores
soma_valores += chunk['Valor'].sum()
total_linhas += len(chunk)
print(f"Processadas {total_linhas} linhas...")
media_valores = soma_valores / total_linhas
print(f"\nProcessamento concluído:")
print(f"Total de linhas: {total_linhas:,}")
print(f"Média dos valores: {media_valores:.2f}")
print(f"Contagem por categoria: {contagem_categorias}")
Conexão com Bancos de Dados SQL
SQLite
import sqlite3
# Conectar e criar uma tabela de exemplo
conexao = sqlite3.connect('banco_empresa.db')
cursor = conexao.cursor()
# Criar tabela de funcionários
cursor.execute('''
CREATE TABLE IF NOT EXISTS funcionarios (
id INTEGER PRIMARY KEY,
nome TEXT NOT NULL,
departamento TEXT,
salario REAL,
data_contratacao TEXT
)
''')
# Inserir dados
funcionarios = [
(1, 'Ana Silva', 'TI', 7500.00, '2020-01-15'),
(2, 'Bruno Costa', 'Marketing', 6000.00, '2021-03-10'),
(3, 'Carlos Oliveira', 'TI', 8000.00, '2019-11-22'),
(4, 'Diana Santos', 'Financeiro', 6500.00, '2022-06-05')
]
cursor.executemany('INSERT OR REPLACE INTO funcionarios VALUES (?, ?, ?, ?, ?)', funcionarios)
conexao.commit()
# Ler dados
print("Todos os funcionários:")
df_sql = pd.read_sql('SELECT * FROM funcionarios', conexao)
print(df_sql)
# Consulta com filtro
print("\nFuncionários de TI com salário > 7000:")
df_filtro = pd.read_sql(
"SELECT nome, salario FROM funcionarios WHERE departamento = 'TI' AND salario > 7000",
conexao
)
print(df_filtro)
# Consulta com agregação
print("\nEstatísticas por departamento:")
df_stats = pd.read_sql('''
SELECT departamento,
COUNT(*) as num_funcionarios,
AVG(salario) as salario_medio,
MIN(salario) as salario_minimo
FROM funcionarios
GROUP BY departamento
''', conexao)
print(df_stats)
conexao.close()
MySQL (Exemplo Conceitual)
# Nota: Este exemplo requer um servidor MySQL em execução e a instalação do pymysql.
# pip install pymysql sqlalchemy
"""
from sqlalchemy import create_engine
# String de conexão
url_conexao = 'mysql+pymysql://usuario:senha@localhost:3306/nome_banco'
motor = create_engine(url_conexao)
# Ler dados
df = pd.read_sql('SELECT * FROM tabela_clientes', motor)
# Escrever dados
df_novo.to_sql('tabela_backup', motor, if_exists='replace', index=False)
# Consulta complexa
df_relatorio = pd.read_sql('''
SELECT c.nome,
SUM(v.valor) as total_vendas,
COUNT(v.id) as num_pedidos
FROM clientes c
JOIN vendas v ON c.id = v.cliente_id
GROUP BY c.id
HAVING total_vendas > 10000
''', motor)
"""
Leitura de Outros Formatos
JSON
# Ler um arquivo JSON
import json
# Dados JSON de exemplo
dados_json = [
{"produto": "A", "preco": 50, "vendas": 100},
{"produto": "B", "preco": 75, "vendas": 80},
{"produto": "C", "preco": 30, "vendas": 150}
]
with open('dados.json', 'w', encoding='utf-8') as f:
json.dump(dados_json, f, ensure_ascii=False, indent=2)
# Carregar em DataFrame
df_json = pd.read_json('dados.json')
print(df_json)
HTML
# Extrair tabelas de páginas HTML
# Exemplo real: url = 'https://exemplo.com/tabela.html'
# tabelas = pd.read_html(url)
# Exemplo local
html_tabela = '''
<table>
<tr><th>Nome</th><th>Idade</th></tr>
<tr><td>Lucas</td><td>28</td></tr>
<tr><td>Maria</td><td>32</td></tr>
</table>
'''
with open('tabela.html', 'w', encoding='utf-8') as f:
f.write(html_tabela)
df_html = pd.read_html('tabela.html')[0]
print(df_html)
Exemplo Prático: Integração de Dados
# Cenário: Integrar dados de diferentes fontes
# Fonte 1: CSV com dados demográficos
demografia = pd.DataFrame({
'cliente_id': [101, 102, 103, 104],
'cidade': ['São Paulo', 'Rio de Janeiro', 'Belo Horizonte', 'Porto Alegre'],
'faixa_etaria': ['25-34', '35-44', '25-34', '45-54']
})
demografia.to_csv('demografia.csv', index=False)
# Fonte 2: Excel com dados de compra
compras = pd.DataFrame({
'cliente_id': [101, 102, 101, 103, 104, 102],
'valor': [250, 180, 320, 410, 190, 275],
'data': pd.date_range('2024-01-01', periods=6)
})
with pd.ExcelWriter('compras.xlsx', engine='openpyxl') as writer:
compras.to_excel(writer, sheet_name='Compras', index=False)
# Fonte 3: Banco de dados com feedbacks
conexao = sqlite3.connect('feedback.db')
pd.DataFrame({
'cliente_id': [101, 102, 103, 104],
'avaliacao': [4.5, 3.8, 4.2, 4.7],
'comentario': ['Ótimo produto', 'Bom atendimento', 'Entrega rápida', 'Excelente']
}).to_sql('feedbacks', conexao, if_exists='replace', index=False)
# Integrar os dados
df_demo = pd.read_csv('demografia.csv')
df_comp = pd.read_excel('compras.xlsx', sheet_name='Compras')
df_feed = pd.read_sql('SELECT * FROM feedbacks', conexao)
# Juntar todos os dados
df_completo = df_demo.merge(df_comp.groupby('cliente_id')['valor'].sum().reset_index(), on='cliente_id')
df_completo = df_completo.merge(df_feed, on='cliente_id')
df_completo.rename(columns={'valor': 'total_gasto'}, inplace=True)
print("Dados integrados:")
print(df_completo)
# Análise por cidade
analise_cidade = df_completo.groupby('cidade').agg({
'total_gasto': ['mean', 'sum'],
'avaliacao': 'mean',
'cliente_id': 'count'
}).round(2)
print("\nAnálise por cidade:")
print(analise_cidade)
conexao.close()
Resumo das Técnicas
- CSV: Use
pd.read_csv()com atenção aos parâmetrossep,encoding,usecolsedtype. - Excel: Use
pd.read_excel()especificandosheet_name. Instale oopenpyxl. - Cdoificação: Enfrente erros de Unicode com
encoding='utf-8-sig'ou'latin-1'. - Arquivos Grandes: Utilize
chunksizepara processamento iterativo e eficiente em memória. - SQL: Use
pd.read_sql()com consultas SQL específicas para otimizar a transferência de dados. - Performance: Sempre leia apenas as colunas necessárias (
usecols) e defina os tipos de dados (dtype) apropriados.