Как сохранить DataFrame в CSV в pandas

Карьерник — квиз-тренажёр в Telegram с 1500+ вопросами для собесов аналитика. SQL, Python, A/B, метрики. Бесплатно.

Базовый синтаксис

df.to_csv('data.csv')

1. Без индекса

По умолчанию pandas сохраняет индекс. Обычно не нужно:

df.to_csv('data.csv', index=False)

Рекомендация: почти всегда используйте index=False, если индекс не несёт смысла.

2. Кодировка

# кириллица — UTF-8 (стандарт)
df.to_csv('data.csv', encoding='utf-8')

# Excel в Windows плохо работает с UTF-8 без BOM
df.to_csv('data.csv', encoding='utf-8-sig')

# старый Windows
df.to_csv('data.csv', encoding='cp1251')

utf-8-sig добавляет BOM — Excel правильно открывает кириллицу.

3. Разделитель

# стандарт: запятая
df.to_csv('data.csv', sep=',')

# для РФ/Excel: точка с запятой (запятая — десятичная часть)
df.to_csv('data.csv', sep=';')

# таб
df.to_csv('data.tsv', sep='\t')

4. Десятичный разделитель

# стандарт: точка
df.to_csv('data.csv', decimal='.')

# для РФ Excel: запятая (1,5 вместо 1.5)
df.to_csv('data.csv', sep=';', decimal=',')

5. Только некоторые колонки

df.to_csv('data.csv', columns=['name', 'age'])

6. Формат чисел

# 2 знака после запятой
df.to_csv('data.csv', float_format='%.2f')

# научная нотация
df.to_csv('data.csv', float_format='%.3e')

7. Обработка NaN

# по умолчанию NaN → пустая строка
df.to_csv('data.csv', na_rep='')

# или заменить
df.to_csv('data.csv', na_rep='N/A')
df.to_csv('data.csv', na_rep='NULL')

8. Даты в определённом формате

# по умолчанию ISO 8601
df.to_csv('data.csv', date_format='%Y-%m-%d')

# DD.MM.YYYY
df.to_csv('data.csv', date_format='%d.%m.%Y')

9. Сжатие

# gzip
df.to_csv('data.csv.gz', compression='gzip')

# zip
df.to_csv('data.csv.zip', compression='zip')

# автоматически по расширению
df.to_csv('data.csv.gz')  # pandas сам определит gzip

Сжатие в 3-10 раз уменьшает размер.

10. По частям (chunks)

Для очень больших DataFrame:

df.to_csv('big.csv', chunksize=10_000)

Записывает по 10k строк за раз, не нагружая память.

11. Append (добавить к существующему)

# первый раз — с заголовком
df1.to_csv('data.csv', index=False)

# добавить
df2.to_csv('data.csv', mode='a', index=False, header=False)

12. В память / на S3

# в память (для отправки по HTTP и т.п.)
csv_str = df.to_csv(index=False)

# на S3 напрямую (нужен s3fs)
df.to_csv('s3://bucket/path/data.csv', index=False)

13. Кавычки вокруг строк

import csv

# принудительно кавычки на всех строковых полях
df.to_csv('data.csv', quoting=csv.QUOTE_ALL)

# только где нужно (default)
df.to_csv('data.csv', quoting=csv.QUOTE_MINIMAL)

14. Полный пример для russian Excel

df.to_csv(
    'report.csv',
    sep=';',
    decimal=',',
    encoding='utf-8-sig',
    index=False,
    date_format='%d.%m.%Y',
    float_format='%.2f',
    na_rep=''
)

Открывается в Excel корректно, с кириллицей и русскими числами.

Альтернативы CSV

Для больших данных или повторного чтения — лучше:

# Parquet — меньше, быстрее
df.to_parquet('data.parquet')

# Feather — очень быстрое чтение
df.to_feather('data.feather')

# Excel (xlsx)
df.to_excel('data.xlsx', sheet_name='Sheet1', index=False)

# JSON
df.to_json('data.json', orient='records', force_ascii=False)

Parquet — стандарт для data engineering: в 5-10 раз меньше CSV, быстрее читается.

Частые ошибки

1. Включить индекс без смысла

# default — с индексом, часто не нужен
df.to_csv('data.csv')

# без индекса
df.to_csv('data.csv', index=False)

2. Кракозябры в Excel

Без utf-8-sig Excel покажет «иероглифы»:

df.to_csv('data.csv', encoding='utf-8-sig')

3. Excel путает разделители

В русском Excel запятая — десятичный. Используйте sep=';' и decimal=','.

4. Потеря типов

CSV — просто текст. int, float, datetime — всё становится строкой при чтении обратно.

Для сохранения типов используйте Parquet / Feather.

5. Огромный DataFrame — OOM

Используйте chunksize или Parquet.

Связанные темы

FAQ

CSV или Parquet?

Parquet быстрее и меньше. CSV нужен для совместимости с Excel и внешними системами.

Кавычки везде или только где надо?

Только где надо (default). Везде — только если обрабатываете через слабый парсер.

Как исключить колонки?

df.drop(columns=['col']).to_csv(...).

Размер CSV большой — что делать?

compression='gzip' или перейти на Parquet.


Тренируйте pandas — откройте тренажёр с 1500+ вопросами для собесов.