Pandas: Leitura e Escrita de Dados
Última atualização: 2026-08-26
Em projetos reais, os dados não surgem do nada no seu código — eles vêm de arquivos CSV, planilhas do Excel, bancos de dados e endpoints de API. O Pandas oferece mais de 20 funções de IO que permitem carregar e salvar dados em diversos formatos com uma única linha de código. Esta seção aborda os 4 formatos mais comuns (CSV / Excel / JSON / SQL), além de dicas práticas para codificação e tratamento de arquivos grandes.
1. O Que Você Aprenderá
- ❶ read_csv / to_csv em profundidade
- ❷ read_excel / to_excel com tratamento de múltiplas abas
- ❸ read_json / to_json tratamento de formato
- ❹ read_sql / to_sql interação com banco de dados
- ❺ Problemas de encoding e estratégias para arquivos grandes (chunksize)
2. O Pesadelo de Codificação do Bob
(1) A Dor: O CSV Abre como Texto Ilegível
Bob recebe um CSV de dados do cliente e carrega com parâmetros padrão — todos os caracteres chineses se transformam em ilegibilidade:
import pandas as pd
# Isso falha ou produz texto ilegível
# df = pd.read_csv('customers.csv') # UnicodeDecodeError!
> **Saída:** Execute isto no seu ambiente local Python (pandas 2.x). O servidor Piston não tem pandas pré-instalado. Por favor, instale-o localmente (`pip install pandas`) e siga alongado. Os valores reais podem variar ligeramente dependendo da sua versão do pandas.
A razão: o arquivo está codificado em GBK, mas o Pandas o lê como UTF-8 por padrão.
(2) A Solução: Especificar a codificação
▶ Exemplo: Tratamento de Codificação (Dificuldade ⭐)
import pandas as pd
from io import StringIO
# Simular CSV codificado em GBK
csv_gbk = "name,age,city\nAlice,28,Beijing\nBob,34,Shanghai"
# Em um cenário real: pd.read_csv('file.csv', encoding='gbk')
# UTF-8 (padrão) — funciona para a maioria dos arquivos modernos
csv_utf8 = "name,age,city\nAlice,28,New York\nBob,34,London"
df = pd.read_csv(StringIO(csv_utf8))
print(df)
# name age city
# 0 Alice 28 New York
# 1 Bob 34 London
> **Saída:** Execute isto no seu ambiente local Python (pandas 2.x). O servidor Piston não tem pandas pré-instalado. Por favor, instale-o localmente (`pip install pandas`) e siga alongado. Os valores reais podem variar ligeramente dependendo da sua versão do pandas.
(3) O Retorno: Funções de IO Concluem em Uma Linha
| Cenário | Uma linha |
|---|---|
| Ler CSV | pd.read_csv('data.csv') |
| Escrever CSV | df.to_csv('out.csv', index=False) |
| Ler Excel | pd.read_excel('data.xlsx') |
| Ler SQL | pd.read_sql('SELECT * FROM t', conn) |
3. Leitura e Escrita de CSV
(1) Parâmetros Comuns do read_csv
▶ Exemplo
> **Saída:** Execute isso no seu ambiente local Python (pandas 2.x). O servidor Piston não tem pandas pré-instalado. Por favor, instale-o localmente (`pip install pandas`) e acompanhe. Os valores reais podem variar ligeiramente dependendo da sua versão do pandas.
: Detalhes dos Parâmetros do read_csv (Dificuldade ⭐⭐)
import pandas as pd
from io import StringIO
csv_data = """product_id,product_name,price,stock,category
P001,Laptop,999.99,50,Electronics
P002,Phone,699.99,120,Electronics
P003,Tablet,349.99,80,Electronics
P004,Monitor,449.99,35,Electronics
P005,Keyboard,79.99,200,Accessories"""
# Leitura básica
df = pd.read_csv(StringIO(csv_data))
print(df.columns) # detectado automaticamente da primeira linha
# Parâmetros principais (mostrados com dados simulados)
# pd.read_csv('file.csv',
# encoding='utf-8', # codificação do arquivo
# sep=',', # delimitador (padrão é vírgula)
# header=0, # número da linha para nomes das colunas
# index_col='product_id', # coluna a ser usada como índice
# usecols=['product_name', 'price'], # carregar apenas essas colunas
# dtype={'price': float, 'stock': int}, # forçar tipos
# na_values=['N/A', 'NULL'], # tratar estes como NaN
# parse_dates=['order_date'], # analisar como datetime
# nrows=1000, # ler apenas as primeiras N linhas
# chunksize=5000 # iterar em pedaços
# )
# Selecionar colunas específicas (economiza memória)
df_selected = pd.read_csv(StringIO(csv_data), usecols=['product_name', 'price'])
print(df_selected)
> **Saída:** Execute isso no seu ambiente local Python (pandas 2.x). O servidor Piston não tem pandas pré-instalado. Por favor, instale-o localmente (`pip install pandas`) e acompanhe. Os valores reais podem variar ligeiramente dependendo da sua versão do pandas.
(2) Salvando com to_csv
▶ Exemplo
> **Saída:** Execute isso no seu ambiente local Python (pandas 2.x). O servidor Piston não tem pandas pré-instalado. Por favor, instale-o localmente (`pip install pandas`) e acompanhe. Os valores reais podem variar ligeiramente dependendo da sua versão do pandas.
: Salvando com to_csv (Dificuldade ⭐)
import pandas as pd
from io import StringIO
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Charlie'],
'age': [28, 34, 25],
'city': ['New York', 'London', 'Tokyo']
})
# Salvar para uma string CSV (simulando saída de arquivo)
output = StringIO()
df.to_csv(output, index=False) # index=False — não salvar números das linhas
print(output.getvalue())
# name,age,city
# Alice,28,New York
# Bob,34,London
# Charlie,25,Tokyo
# Arquivo real: df.to_csv('output.csv', index=False, encoding='utf-8')
# Anexar a um arquivo existente
# df.to_csv('output.csv', mode='a', header=False, index=False)
> **Saída:** Execute isso no seu ambiente local Python (pandas 2.x). O servidor Piston não tem pandas pré-instalado. Por favor, instale-o localmente (`pip install pandas`) e acompanhe. Os valores reais podem variar ligeiramente dependendo da sua versão do pandas.
4. Leitura e Escrita de Excel
(1) read_excel com Múltiplas Abas
▶ Exemplo
> **Saída:** Execute isto em seu ambiente Python local (pandas 2.x). O servidor Piston não tem o pandas pré-instalado. Por favor, instale-o localmente (`pip install pandas`) e acompanhe. Os valores reais podem variar ligeramente dependendo da sua versão do pandas.
: Leitura de Excel Multi-Abas (Dificuldade ⭐⭐)
import pandas as pd
from io import BytesIO
# Create a multi-sheet Excel file in memory
buffer = BytesIO()
df1 = pd.DataFrame({'name': ['Alice', 'Bob'], 'score': [85, 92]})
df2 = pd.DataFrame({'product': ['Laptop', 'Phone'], 'price': [999, 699]})
with pd.ExcelWriter(buffer) as writer:
df1.to_excel(writer, sheet_name='Students', index=False)
df2.to_excel(writer, sheet_name='Products', index=False)
buffer.seek(0)
# Read specific sheet
students = pd.read_excel(buffer, sheet_name='Students')
print(students)
# Read all sheets as dict
buffer.seek(0)
all_sheets = pd.read_excel(buffer, sheet_name=None) # dict of DataFrames
print(all_sheets.keys()) # dict_keys(['Students', 'Products'])
# Read by sheet position
buffer.seek(0)
second_sheet = pd.read_excel(buffer, sheet_name=1) # 0-indexed
print(second_sheet)
> **Saída:** Execute isto em seu ambiente Python local (pandas 2.x). O servidor Piston não tem o pandas pré-instalado. Por favor, instale-o localmente (`pip install pandas`) e acompanhe. Os valores reais podem variar ligeramente dependendo da sua versão do pandas.
pip install openpyxl (para .xlsx) ou pip install xlrd (para .xls). O Pandas 2.x usa o openpyxl por padrão.
(2) Salvando com to_excel
▶ Exemplo
> **Saída:** Execute isto em seu ambiente Python local (pandas 2.x). O servidor Piston não tem o pandas pré-instalado. Por favor, instale-o localmente (`pip install pandas`) e acompanhe. Os valores reais podem variar ligeramente dependendo da sua versão do pandas.
: Salvamento e Formatação de Excel (Dificuldade ⭐)
import pandas as pd
from io import BytesIO
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Charlie'],
'salary': [75000, 92000, 68000]
})
# Save to single sheet
buffer = BytesIO()
df.to_excel(buffer, sheet_name='Employees', index=False)
# Save multiple DataFrames to different sheets
buffer2 = BytesIO()
with pd.ExcelWriter(buffer2) as writer:
df.to_excel(writer, sheet_name='Employees', index=False)
df.describe().to_excel(writer, sheet_name='Statistics')
> **Saída:** Execute isto em seu ambiente Python local (pandas 2.x). O servidor Piston não tem o pandas pré-instalado. Por favor, instale-o localmente (`pip install pandas`) e acompanhe. Os valores reais podem variar ligeramente dependendo da sua versão do pandas.
5. Leitura e Escrita de JSON
(1) Tipos de Formato JSON
▶ Exemplo
> **Saída:** Execute isso no seu ambiente Python local (pandas 2.x). O servidor Piston não tem o pandas pré-instalado. Por favor, instale-o localmente (`pip install pandas`) e acompanhe. Os valores reais podem variar ligeiramente dependendo da sua versão do pandas.
: Leitura e Escrita em Múltiplos Formatos JSON (Dificuldade ⭐⭐)
import pandas as pd
from io import StringIO
# orient='records' (o mais comum para APIs)
json_records = '[{"name":"Alice","age":28},{"name":"Bob","age":34}]'
df = pd.read_json(StringIO(json_records), orient='records')
print(df)
# name age
# 0 Alice 28
# 1 Bob 34
# orient='columns' (orientado a colunas)
json_cols = '{"name":{"0":"Alice","1":"Bob"},"age":{"0":28,"1":34}}'
df2 = pd.read_json(StringIO(json_cols), orient='columns')
print(df2)
# orient='index' (orientado a linhas)
json_idx = '{"0":{"name":"Alice","age":28},"1":{"name":"Bob","age":34}}'
df3 = pd.read_json(StringIO(json_idx), orient='index')
print(df3)
# Escrever para JSON
output = df.to_json(orient='records', indent=2)
print(output)
> **Saída:** Execute isso no seu ambiente Python local (pandas 2.x). O servidor Piston não tem o pandas pré-instalado. Por favor, instale-o localmente (`pip install pandas`) e acompanhe. Os valores reais podem variar ligeiramente dependendo da sua versão do pandas.
(2) Comparação dos orient do JSON
| orient | Estrutura | Caso de Uso |
|---|---|---|
| records | [{col:val}, ...] |
Respostas de API (o mais comum) |
| columns | {col:{idx:val}} |
Orientado a colunas |
| index | {idx:{col:val}} |
Orientado a linhas |
| split | {index:[], columns:[], data:[[]]} |
Decomposição completa |
| values | [[v1,v2], ...] |
Dados brutos sem rótulos |
6. Leitura e Escrita com SQL
(1) Consultas ao Banco de Dados com read_sql
▶ Exemplo
> **Saída:** Execute isso no seu ambiente Python local (pandas 2.x). O servidor Piston não tem o pandas pré-instalado. Por favor, instale-o localmente (`pip install pandas`) e acompanhe. Os valores reais podem variar ligeiramente dependendo da sua versão do pandas.
: Interação com Banco de Dados SQL (Dificuldade ⭐⭐)
import pandas as pd
import sqlite3
from io import StringIO
# Crie um banco de dados SQLite em memória (para demonstração)
conn = sqlite3.connect(':memory:')
# Escreva dados no SQL
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Charlie'],
'department': ['Sales', 'Engineering', 'Marketing'],
'salary': [75000, 92000, 68000]
})
df.to_sql('employees', conn, if_exists='replace', index=False)
# Leia a tabela inteira
df_read = pd.read_sql('SELECT * FROM employees', conn)
print(df_read)
# Leia com consulta SQL
high_salary = pd.read_sql(
'SELECT name, salary FROM employees WHERE salary > 70000',
conn
)
print(high_salary)
# name salary
# 0 Alice 75000
# 1 Bob 92000
# Leia com parâmetros (seguro contra injeção SQL)
dept = 'Engineering'
result = pd.read_sql(
'SELECT * FROM employees WHERE department = ?',
conn,
params=[dept]
)
print(result)
conn.close()
> **Saída:** Execute isso no seu ambiente Python local (pandas 2.x). O servidor Piston não tem o pandas pré-instalado. Por favor, instale-o localmente (`pip install pandas`) e acompanhe. Os valores reais podem variar ligeiramente dependendo da sua versão do pandas.
pip install psycopg2 (PostgreSQL), pip install pymysql (MySQL).
7. Estratégias para Arquivos Grandes
(1) Leitura em Pedaços com chunksize
▶ Exemplo
> **Saída:** Execute isso no seu ambiente Python local (pandas 2.x). O servidor Piston não tem pandas pré-instalado. Por favor, instale-o localmente (`pip install pandas`) e acompanhe. Os valores reais podem variar ligeiramente dependendo da sua versão do pandas.
: Tratamento de Arquivos Grandes com chunksize (Dificuldade ⭐⭐)
import pandas as pd
from io import StringIO
# Simula um CSV grande
csv_large = "id,value\n" + "\n".join([f"{i},{i*10}" for i in range(100)])
# Lê em pedaços de 30 linhas
chunks = pd.read_csv(StringIO(csv_large), chunksize=30)
total_sum = 0
total_count = 0
for chunk in chunks:
total_sum += chunk['value'].sum()
total_count += len(chunk)
print(f"Total rows: {total_count}")
print(f"Sum of values: {total_sum}")
# Alternativa: processar e salvar cada pedaço
# for i, chunk in enumerate(chunks):
# chunk.to_csv(f'chunk_{i}.csv', index=False)
> **Saída:** Execute isso no seu ambiente Python local (pandas 2.x). O servidor Piston não tem pandas pré-instalado. Por favor, instale-o localmente (`pip install pandas`) e acompanhe. Os valores reais podem variar ligeiramente dependendo da sua versão do pandas.
(2) Carregando Apenas Colunas Selecionadas para Economizar Memória
▶ Exemplo
> **Saída:** Execute isso no seu ambiente Python local (pandas 2.x). O servidor Piston não tem pandas pré-instalado. Por favor, instale-o localmente (`pip install pandas`) e acompanhe. Os valores reais podem variar ligeiramente dependendo da sua versão do pandas.
: Carregamento Seletivo de Colunas (Dificuldade ⭐)
import pandas as pd
from io import StringIO
csv_data = """id,name,age,salary,department,address,phone
1,Alice,28,75000,Sales,123 Main St,555-0100
2,Bob,34,92000,Engineering,456 Oak Ave,555-0200
3,Charlie,25,68000,Marketing,789 Pine Rd,555-0300"""
# Carrega apenas as colunas que você precisa
df = pd.read_csv(StringIO(csv_data), usecols=['name', 'salary', 'department'])
print(df)
# Também funciona: usecols=[1, 3, 4] (por posição)
> **Saída:** Execute isso no seu ambiente Python local (pandas 2.x). O servidor Piston não tem pandas pré-instalado. Por favor, instale-o localmente (`pip install pandas`) e acompanhe. Os valores reais podem variar ligeiramente dependendo da sua versão do pandas.
(3) Comparação de Formatos de IO
| Formato | Leitura | Escrita | Velocidade | Tamanho | Melhor Para |
|---|---|---|---|---|---|
| CSV | read_csv | to_csv | Média | Médio | Intercâmbio geral |
| Excel | read_excel | to_excel | Lenta | Grande | Relatórios de negócios |
| JSON | read_json | to_json | Lenta | Grande | API / Web |
| SQL | read_sql | to_sql | Lenta | — | Bancos de dados |
| Parquet | read_parquet | to_parquet | Rápida | Pequeno | Armazenamento de big data |
| HDF5 | read_hdf | to_hdf | Rápida | Pequeno | Dados científicos |
| Feather | read_feather | to_feather | Mais Rápida | Pequeno | Armazenamento temporário |
8. Exemplo Completo: Carregar → Limpar → Exportar em Múltiplos Formatos
(5) ▶ Árvore de Decisão de IO
graph TB
A[Data Source] --> B{File size?}
B -->|Small| C[CSV / Excel / JSON]
B -->|Medium| D[CSV + chunksize]
B -->|Large| E[Parquet / Feather]
A --> F{Need a database?}
F -->|Yes| G[read_sql / to_sql]
F -->|No| H{Need an API?}
H -->|Yes| I[read_json]
H -->|No| J[read_csv]
> **Saída:** Execute isso em seu ambiente Python local (pandas 2.x). O servidor Piston não tem o pandas pré-instalado. Por favor, instale-o localmente (`pip install pandas`) e siga alongado. Os valores reais podem variar ligeiramente dependendo da sua versão do pandas.
▶ Exemplo
> **Saída:** Execute isso em seu ambiente Python local (pandas 2.x). O servidor Piston não tem o pandas pré-instalado. Por favor, instale-o localmente (`pip install pandas`) e siga alongado. Os valores reais podem variar ligeiramente dependendo da sua versão do pandas.
: Pipeline Completo de IO (Dificuldade ⭐⭐⭐)
import pandas as pd
import sqlite3
from io import StringIO, BytesIO
# ============================================
# Exemplo abrangente: Pipeline completo de IO
# Carregar CSV → Limpar → Exportar CSV/Excel/JSON/SQL
# ============================================
# 1. Carregar de CSV
csv_data = """name,age,salary,department,hire_date
Alice,28,75000,Sales,2022-03-15
Bob,34,92000,Engineering,2019-08-01
Charlie,25,NaN,Marketing,2023-01-10
Carol,30,88000,Sales,2020-06-20
David,45,105000,Management,2015-11-01"""
df = pd.read_csv(StringIO(csv_data), na_values=['NaN'])
# 2. Limpar dados
df['salary'] = df['salary'].fillna(df['salary'].median())
df['hire_date'] = pd.to_datetime(df['hire_date'])
print("=== Dados Limpos ===")
print(df)
# 3. Exportar para CSV
csv_out = StringIO()
df.to_csv(csv_out, index=False)
print(f"\n✅ Exportação CSV: {len(csv_out.getvalue())} caracteres")
# 4. Exportar para Excel
excel_out = BytesIO()
with pd.ExcelWriter(excel_out) as writer:
df.to_excel(writer, sheet_name='Employees', index=False)
df.describe().to_excel(writer, sheet_name='Stats')
print(f"✅ Exportação Excel: {len(excel_out.getvalue())} bytes, 2 planilhas")
# 5. Exportar para JSON
json_out = df.to_json(orient='records', indent=2, date_format='iso')
print(f"✅ Exportação JSON: {len(json_out)} caracteres")
# 6. Exportar para SQL
conn = sqlite3.connect(':memory:')
df.to_sql('employees', conn, if_exists='replace', index=False)
df_from_sql = pd.read_sql('SELECT * FROM employees', conn)
print(f"✅ Round-trip SQL: {len(df_from_sql)} linhas")
conn.close()
> **Saída:** Execute isso em seu ambiente Python local (pandas 2.x). O servidor Piston não tem o pandas pré-instalado. Por favor, instale-o localmente (`pip install pandas`) e siga alongado. Os valores reais podem variar ligeiramente dependendo da sua versão do pandas.
❓ Perguntas Frequentes
encoding='utf-8' primeiro; se falhar, use encoding='gbk'. Um fallback universal é encoding='latin1' (não gerará erro, mas pode produzir texto ilegível). Você também pode usar a biblioteca chardet para detectar automaticamente a codificação..xlsx requerem pip install openpyxl, e arquivos .xls requerem pip install xlrd. O Pandas 2.x usa o mecanismo openpyxl por padrão. Se você vir um erro "Missing optional dependency", basta instalar a biblioteca correspondente.pd.read_csv(path, chunksize=N) retorna um objeto TextFileReader. Cada iteração gera um DataFrame de N linhas. Ideal para arquivos que excedem a memória disponível — processe por partes, agregue por partes, salve por partes. Nota: o modo chunksize não suporta acesso aleatório; lê apenas sequencialmente.usecols: pd.read_csv(path, usecols=['col1', 'col3']) seleciona por nome da coluna, ou usecols=[0, 2, 4] seleciona por posição. Carregar apenas as colunas necessárias pode reduzir drasticamente o uso de memória, especialmente para tabelas largas (100+ colunas mas você só precisa de 5).pip install pyarrow) e não é adequado para inspeção humana direta. Recomendação: use CSV para troca de dados brutos e Parquet para armazenar dados processados.index=False para omiti-lo. Se seu Index contém rótulos significativos (como datas), você pode mantê-lo com index=True.📖 Resumo
- read_csv é a função de IO mais comumente utilizada. Parâmetros principais: encoding / sep / usecols / dtype / parse_dates
- Ao salvar com to_csv, use index=False para evitar a escrita de números de linha sem significado
- A leitura e escrita de Excel requerem openpyxl e suportam operações com múltiplas planilhas (via parâmetro sheet_name)
- JSON possui 5 modos de orientação; use records para interação com APIs
- A leitura e escrita de SQL funcionam através de conexões DB-API e suportam consultas parametrizadas para prevenir injeção
- Para arquivos grandes, use chunksize para leitura em pedaços + usecols para carregamento seletivo de colunas
- Parquet/HDF5/Feather são 5 a 50 vezes mais rápidos que CSV e ideais para armazenamento de big data
📝 Exercícios
- Básico (Dificuldade ⭐): Use StringIO para simular um arquivo CSV, carregue-o com read_csv (especificando dtype e usecols), depois salve-o com to_csv (index=False).
- Intermediário (Dificuldade ⭐⭐): Crie 2 DataFrames, escreva-os em diferentes planilhas no mesmo arquivo Excel usando ExcelWriter, depois leia todas as planilhas de volta usando read_excel com sheet_name=None.
- Desafio (Dificuldade ⭐⭐⭐): Simule um CSV com 1000 linhas (contendo valores NaN e uma coluna de data), depois complete o seguinte: read_csv (com na_values/parse_dates/dtype) → preencha valores ausentes → exporte em três formatos: to_csv/to_json/to_sql → leia de volta com read_json para verificar a consistência.