Pandas DataFrame para CSV: Guia Completo de to_csv()
Updated on
Voce limpou os dados, transformou cada coluna e executou sua analise. Agora precisa compartilhar os resultados -- e o arquivo CSV que voce exporta abre com caracteres ilegiveis no Excel, uma coluna de indice indesejada, ou um arquivo de 4 GB que trava o notebook do seu colega. Exportar um DataFrame do Pandas para CSV parece simples ate que codificacao, separadores, compressao e desempenho com arquivos grandes transformem uma unica linha de codigo em uma sessao de depuracao.
Esses problemas sao comuns porque to_csv() tem mais de 20 parametros, e os valores padrao nem sempre correspondem ao que os consumidores downstream esperam. Uma codificacao errada quebra texto nao-ASCII. Um index=False ausente adiciona uma coluna misteriosa. Sem compressao, um conjunto de dados razoavel se torna um anexo superdimensionado.
O metodo DataFrame.to_csv() lida com todos esses casos quando voce sabe quais parametros definir. Este guia percorre cada cenario pratico -- desde exportacao basica ate escrita em blocos de DataFrames com milhoes de linhas -- para que voce possa exportar dados corretamente na primeira tentativa.
Uso Basico
A chamada mais simples escreve um DataFrame em um arquivo CSV no diretorio de trabalho atual:
import pandas as pd
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Charlie'],
'age': [28, 35, 42],
'salary': [72000, 88000, 95000]
})
df.to_csv('employees.csv')Isso cria employees.csv com o seguinte conteudo:
,name,age,salary
0,Alice,28,72000
1,Bob,35,88000
2,Charlie,42,95000Note a primeira coluna -- esse e o indice do DataFrame. Na maioria das vezes voce nao o quer. Corrija com index=False:
df.to_csv('employees.csv', index=False)Saida:
name,age,salary
Alice,28,72000
Bob,35,88000
Charlie,42,95000Assinatura Completa do Metodo
Aqui esta a assinatura completa de to_csv() com os parametros mais usados:
DataFrame.to_csv(
path_or_buf=None, # caminho do arquivo ou buffer
sep=',', # delimitador
na_rep='', # string para valores ausentes
float_format=None, # formato para floats
columns=None, # subconjunto de colunas
header=True, # escrever nomes de colunas
index=True, # escrever indice de linhas
index_label=None, # rotulo da coluna de indice
mode='w', # modo de escrita ('w', 'a', 'x')
encoding=None, # codificacao (padrao utf-8)
compression='infer',# tipo de compressao
quoting=None, # constante csv.QUOTE_*
lineterminator=None,# caractere de fim de linha
chunksize=None, # linhas por bloco
date_format=None, # formato para datas
errors='strict', # tratamento de erros de codificacao
)Parametros Principais Explicados
sep -- Delimitadores Personalizados
Nem todo sistema le virgulas. Use sep para mudar o delimitador:
import pandas as pd
df = pd.DataFrame({
'product': ['Widget A', 'Widget B'],
'price': [19.99, 29.99]
})
# Separado por tabulacao
df.to_csv('products.tsv', sep='\t', index=False)
# Separado por ponto e virgula (comum em configuracoes europeias)
df.to_csv('products_eu.csv', sep=';', index=False)
# Separado por pipe
df.to_csv('products.txt', sep='|', index=False)columns -- Exportar um Subconjunto
Escreva apenas colunas especificas em vez do DataFrame inteiro:
import pandas as pd
df = pd.DataFrame({
'id': [1, 2, 3],
'name': ['Alice', 'Bob', 'Charlie'],
'email': ['a@x.com', 'b@x.com', 'c@x.com'],
'internal_score': [0.87, 0.92, 0.78]
})
# Exportar apenas as colunas que o cliente precisa
df.to_csv('export.csv', columns=['id', 'name', 'email'], index=False)header -- Controlar Nomes de Colunas
import pandas as pd
df = pd.DataFrame({
'name': ['Alice', 'Bob'],
'score': [85, 92]
})
# Sem linha de cabecalho
df.to_csv('no_header.csv', header=False, index=False)
# Nomes de cabecalho personalizados
df.to_csv('custom_header.csv', header=['Nome Completo', 'Nota do Teste'], index=False)na_rep -- Representar Valores Ausentes
Por padrao, valores NaN se tornam strings vazias. Use na_rep para torna-los explicitos:
import pandas as pd
import numpy as np
df = pd.DataFrame({
'sensor': ['A', 'B', 'C'],
'reading': [23.5, np.nan, 18.2]
})
# Padrao: string vazia para NaN
df.to_csv('readings_default.csv', index=False)
# sensor,reading
# A,23.5
# B,
# C,18.2
# Marcador explicito de valor ausente
df.to_csv('readings_marked.csv', na_rep='NULL', index=False)
# sensor,reading
# A,23.5
# B,NULL
# C,18.2float_format -- Controlar Precisao Decimal
import pandas as pd
df = pd.DataFrame({
'item': ['Widget', 'Gadget'],
'price': [19.999999, 42.123456]
})
# Duas casas decimais
df.to_csv('prices.csv', float_format='%.2f', index=False)
# item,price
# Widget,20.00
# Gadget,42.12date_format -- Formatar Colunas de Data/Hora
import pandas as pd
df = pd.DataFrame({
'event': ['Launch', 'Review'],
'date': pd.to_datetime(['2026-03-15 14:30:00', '2026-04-01 09:00:00'])
})
# Apenas data ISO (sem hora)
df.to_csv('events.csv', date_format='%Y-%m-%d', index=False)
# event,date
# Launch,2026-03-15
# Review,2026-04-01Tratamento de Codificacao e Caracteres Especiais
Codificacao e a causa numero um de arquivos CSV com caracteres ilegiveis. A codificacao padrao em to_csv() e utf-8, que funciona para a maioria dos sistemas. Mas o Excel no Windows espera um BOM (Byte Order Mark) para exibir corretamente caracteres nao-ASCII.
UTF-8 (Padrao)
import pandas as pd
df = pd.DataFrame({
'city': ['Zurique', 'Munique', 'Toquio'],
'greeting': ['Ola', 'Servus', 'Konnichiwa']
})
# UTF-8 padrao
df.to_csv('cities.csv', index=False, encoding='utf-8')UTF-8 com BOM para Excel
Se seu CSV contem caracteres acentuados, texto CJK ou simbolos especiais e precisa abrir corretamente no Microsoft Excel:
import pandas as pd
df = pd.DataFrame({
'city': ['Zurique', 'Munique', 'Sao Paulo', 'Pequim'],
'population': [434000, 1472000, 12330000, 21540000]
})
# utf-8-sig adiciona um BOM que o Excel reconhece
df.to_csv('cities_excel.csv', index=False, encoding='utf-8-sig')Outras Codificacoes
import pandas as pd
df = pd.DataFrame({'col': ['data']})
# Latin-1 para sistemas europeus ocidentais legados
df.to_csv('legacy.csv', index=False, encoding='latin-1')
# Shift-JIS para sistemas japoneses legados
df.to_csv('japanese.csv', index=False, encoding='shift_jis')| Codificacao | Quando Usar | Compativel com Excel? |
|---|---|---|
utf-8 | Padrao para maioria dos sistemas, APIs, bancos de dados | Parcial (sem BOM) |
utf-8-sig | Excel no Windows com texto nao-ASCII | Sim |
latin-1 / iso-8859-1 | Sistemas europeus ocidentais legados | Sim |
shift_jis | Sistemas japoneses legados | Sim |
cp1252 | Windows europeu ocidental | Sim |
DataFrames Grandes: Compressao e Chunking
Compressao
Compressao reduz o tamanho do arquivo em 60-90% sem perda de dados. Pandas suporta multiplos formatos:
import pandas as pd
import numpy as np
# Criar um DataFrame grande
df = pd.DataFrame({
'id': range(1_000_000),
'value': np.random.randn(1_000_000),
'category': np.random.choice(['A', 'B', 'C', 'D'], 1_000_000)
})
# Compressao gzip (mais comum)
df.to_csv('large_data.csv.gz', index=False, compression='gzip')
# Compressao zip
df.to_csv('large_data.zip', index=False, compression='zip')
# Compressao bz2 (menor mas mais lento)
df.to_csv('large_data.csv.bz2', index=False, compression='bz2')
# Zstandard (rapido, boa razao -- requer pacote zstandard)
df.to_csv('large_data.csv.zst', index=False, compression='zstd')| Compressao | Extensao | Velocidade | Reducao de Tamanho | Leitura |
|---|---|---|---|---|
| Nenhuma | .csv | Escrita mais rapida | 0% | pd.read_csv('f.csv') |
| gzip | .csv.gz | Moderada | 70-85% | pd.read_csv('f.csv.gz') |
| zip | .zip | Moderada | 70-85% | pd.read_csv('f.zip') |
| bz2 | .csv.bz2 | Lenta | 75-90% | pd.read_csv('f.csv.bz2') |
| zstd | .csv.zst | Rapida | 70-85% | pd.read_csv('f.csv.zst') |
Pandas infere automaticamente o formato de compressao pela extensao do arquivo, entao compression='infer' (o padrao) geralmente funciona.
Chunksize -- Escrever em Lotes
Para DataFrames muito grandes que sobrecarregam a memoria, escreva em blocos:
import pandas as pd
import numpy as np
df = pd.DataFrame({
'id': range(5_000_000),
'value': np.random.randn(5_000_000)
})
# Escrever 500.000 linhas por vez
df.to_csv('huge_data.csv', index=False, chunksize=500_000)O parametro chunksize nao reduz o tamanho final do arquivo -- ele controla quantas linhas sao gravadas no disco de uma vez. Isso pode ajudar a reduzir o pico de uso de memoria durante a operacao de escrita.
Escrever em String ou Buffer
Voce nem sempre escreve em um arquivo. As vezes precisa do CSV como string para uma chamada de API, insercao em banco de dados ou processamento em memoria:
import pandas as pd
df = pd.DataFrame({
'name': ['Alice', 'Bob'],
'score': [85, 92]
})
# Obter CSV como string
csv_string = df.to_csv(index=False)
print(csv_string)
# name,score
# Alice,85
# Bob,92Escrever em StringIO ou BytesIO
import pandas as pd
from io import StringIO, BytesIO
df = pd.DataFrame({
'x': [1, 2, 3],
'y': [4, 5, 6]
})
# Buffer StringIO
buffer = StringIO()
df.to_csv(buffer, index=False)
csv_text = buffer.getvalue()
# Buffer BytesIO (util para respostas HTTP, uploads S3)
byte_buffer = BytesIO()
df.to_csv(byte_buffer, index=False, encoding='utf-8')
csv_bytes = byte_buffer.getvalue()Esse padrao e comum ao fazer upload de dados CSV para armazenamento em nuvem (S3, GCS) sem criar um arquivo local.
Adicionar a um CSV Existente
Para adicionar linhas a um arquivo existente sem sobrescreve-lo, use mode='a' e header=False:
import pandas as pd
# Primeiro lote -- escrever com cabecalho
df1 = pd.DataFrame({'name': ['Alice'], 'score': [85]})
df1.to_csv('results.csv', index=False)
# Segundo lote -- adicionar sem duplicar o cabecalho
df2 = pd.DataFrame({'name': ['Bob', 'Charlie'], 'score': [92, 78]})
df2.to_csv('results.csv', mode='a', header=False, index=False)O arquivo resultante tem uma linha de cabecalho seguida de tres linhas de dados. Omitir header=False inseriria uma segunda linha de cabecalho no meio dos dados.
Aspas e Escape
Campos contendo o delimitador, quebras de linha ou aspas precisam de tratamento adequado. Pandas lida com isso automaticamente, mas voce pode controlar o comportamento:
import pandas as pd
import csv
df = pd.DataFrame({
'name': ['O\'Brien', 'Smith, Jr.', 'Alice "Ace" Wong'],
'notes': ['Contem apostrofo', 'Contem virgula', 'Contem aspas']
})
# Padrao: aspas apenas quando necessario (QUOTE_MINIMAL)
df.to_csv('minimal.csv', index=False)
# Aspas em todos os campos
df.to_csv('all_quoted.csv', index=False, quoting=csv.QUOTE_ALL)
# Aspas apenas em campos nao numericos
df.to_csv('nonnumeric.csv', index=False, quoting=csv.QUOTE_NONNUMERIC)Comparacao de Formatos de Exportacao: to_csv() vs to_excel() vs to_parquet()
Escolher o formato de exportacao correto depende de quem consome o arquivo e do seu tamanho:
| Caracteristica | to_csv() | to_excel() | to_parquet() |
|---|---|---|---|
| Formato do arquivo | Texto puro | Binario (xlsx) | Binario (colunar) |
| Legivel por humanos | Sim | Via Excel/Sheets | Nao |
| Tamanho do arquivo (1M linhas) | ~50-100 MB | ~30-60 MB | ~5-15 MB |
| Velocidade de escrita | Rapida | Lenta | Rapida |
| Velocidade de leitura | Moderada | Lenta | Muito rapida |
| Preservacao de tipos | Nao (tudo strings) | Parcial | Completa |
| Requer biblioteca extra | Nao | openpyxl | pyarrow / fastparquet |
| Suporte a compressao | gzip, zip, bz2, zstd | Integrado | Integrado (snappy, gzip) |
| Melhor para | Interoperabilidade, APIs, compartilhamento rapido | Usuarios de negocio, usuarios Excel | Pipelines de analise, big data |
Regra geral: Use CSV para compartilhar dados com usuarios nao tecnicos ou sistemas externos. Use Parquet para pipelines internos onde velocidade e fidelidade de tipos importam. Use Excel quando o destinatario precisa de formatacao ou multiplas planilhas.
Armadilhas Comuns e Como Evita-las
1. Coluna de Indice Indesejada
A reclamacao mais frequente. Sempre passe index=False a menos que seu indice contenha dados significativos:
# Errado -- adiciona coluna misteriosa "Unnamed: 0" ao ler
df.to_csv('data.csv')
# Correto
df.to_csv('data.csv', index=False)2. Colunas Sem Nome na Releitura
Se voce exportou com indice e depois leu o arquivo, voce obtem uma coluna Unnamed: 0:
import pandas as pd
# Lendo CSV que foi exportado com indice
df = pd.read_csv('data.csv', index_col=0) # dizer ao read_csv qual coluna e o indice3. Perda de Precisao de Data/Hora
Sem date_format, colunas de data/hora sao exportadas como timestamps completos incluindo microssegundos. Controle isso explicitamente:
import pandas as pd
df = pd.DataFrame({
'ts': pd.to_datetime(['2026-01-15 08:30:00.123456'])
})
df.to_csv('ts.csv', index=False, date_format='%Y-%m-%d %H:%M:%S')4. Problemas de Arredondamento de Floats
Numeros de ponto flutuante podem produzir digitos finais inesperados:
import pandas as pd
df = pd.DataFrame({'val': [0.1 + 0.2]})
df.to_csv('float.csv', index=False)
# val
# 0.30000000000000004
df.to_csv('float_clean.csv', index=False, float_format='%.2f')
# val
# 0.305. Tipos Mistos em uma Coluna
Se uma coluna tem tipos mistos (inteiros e strings), to_csv() converte tudo em strings. Verifique seus tipos de dados antes de exportar:
import pandas as pd
df = pd.DataFrame({'id': [1, 2, 'three']})
print(df.dtypes)
# id object <-- tipo misto
# Limpar antes de exportar
df['id'] = pd.to_numeric(df['id'], errors='coerce')
df.to_csv('clean.csv', index=False)Visualize Seus Dados Antes de Exportar com PyGWalker
Antes de exportar um DataFrame para CSV, e util verificar se os dados estao corretos. PyGWalker (opens in a new tab) transforma qualquer DataFrame do Pandas em uma interface visual interativa dentro do Jupyter Notebook -- arraste e solte colunas para criar graficos sem escrever codigo de plotagem:
import pandas as pd
import pygwalker as pyg
df = pd.read_csv('raw_data.csv')
# Explorar visualmente antes de exportar
walker = pyg.walk(df)
# Quando satisfeito, exportar
df.to_csv('verified_export.csv', index=False, encoding='utf-8-sig')Esse fluxo de trabalho detecta problemas como valores nulos inesperados, outliers ou tipos de dados incorretos antes que eles cheguem ao consumidor do CSV.
FAQ
Como exporto um DataFrame do Pandas para CSV sem o indice?
Passe index=False para to_csv(): df.to_csv('file.csv', index=False). Isso evita que o indice de linhas seja escrito como a primeira coluna. Ao ler o arquivo de volta, voce nao vera uma coluna extra Unnamed: 0.
Como lido com caracteres especiais e codificacao ao exportar para CSV?
Use encoding='utf-8-sig' se o CSV precisa abrir corretamente no Microsoft Excel com caracteres nao-ASCII (letras acentuadas, texto CJK). Para sistemas padrao e APIs, o encoding='utf-8' padrao funciona. Para sistemas legados, use a codificacao especifica que eles requerem (latin-1, shift_jis, etc.).
Como comprimo um arquivo CSV grande ao exportar do Pandas?
Adicione uma extensao de compressao ao nome do arquivo e o Pandas cuida do resto: df.to_csv('data.csv.gz', index=False) cria um arquivo comprimido com gzip. Voce tambem pode definir compression='gzip', 'zip', 'bz2' ou 'zstd' explicitamente. Arquivos comprimidos sao tipicamente 70-90% menores e podem ser lidos diretamente com pd.read_csv().
Posso adicionar dados a um arquivo CSV existente em vez de sobrescreve-lo?
Sim. Use mode='a' e header=False: df.to_csv('file.csv', mode='a', header=False, index=False). mode='a' abre o arquivo para adicao, e header=False evita escrever um cabecalho duplicado no meio do arquivo.
Qual e a diferenca entre to_csv() e to_parquet() no Pandas?
to_csv() produz um arquivo de texto legivel por humanos mas perde informacao de tipos (tudo se torna strings). to_parquet() cria um arquivo binario compacto que preserva tipos de dados (inteiros, floats, datas), e lido 5-10x mais rapido e e 5-10x menor. Use CSV para compartilhar com usuarios nao tecnicos ou sistemas externos. Use Parquet para pipelines de dados internos onde desempenho e fidelidade de tipos importam.
Conclusao
DataFrame.to_csv() e a forma padrao de exportar dados do Pandas para arquivos CSV. Para exportacoes limpas, sempre passe index=False. Use encoding='utf-8-sig' quando compatibilidade com Excel for importante. Comprima arquivos grandes com gzip ou zstd para reduzir o tamanho em 70-90%. Controle a precisao decimal com float_format, trate valores ausentes com na_rep e adicione a arquivos existentes com mode='a'. Para pipelines de dados onde preservacao de tipos e velocidade importam, considere to_parquet() em vez disso. Antes de exportar, verifique seus dados visualmente com ferramentas como PyGWalker para detectar problemas cedo.