Работа с CSV-файлами в Python: практическое руководство
CSV — формат, с которым рано или поздно столкнётся любой разработчик: выгрузка
из 1С, экспорт из Google Sheets, отчёты из CRM, открытые данные госорганов.
Это руководство собирает в одном месте практические рецепты обработки CSV:
стандартный модуль csv, библиотека pandas и решения частых проблем
(кодировки, разделители, типы данных).
Если только знакомитесь с модулем — начните с Модуль csv — работа с CSV-файлами в Python. Эта статья сосредоточена на прикладных задачах.
Какой инструмент выбрать
Задача Что брать
----------------------------------------------- ---------------------
просто прочитать/записать файл csv (stdlib)
потоковая обработка миллионов строк csv (stdlib)
аналитика, группировки, агрегаты pandas
join, merge, преобразования таблиц pandas
мелкие фильтры в скрипте csv (stdlib)
нужны графики и статистика pandas + matplotlib
Главное правило: модуль csv — для построчной обработки и минимальной зависимости от сторонних библиотек. pandas — когда нужны таблицы целиком и аналитика.
Подготовка: пример данных
Будем работать с файлом sales.csv:
date,product,city,amount,price
2026-05-01,Arduino UNO,Алматы,3,15000
2026-05-01,Robot Phobo,Астана,1,49000
2026-05-02,Arduino UNO,Шымкент,2,15000
2026-05-02,ESP32,Алматы,5,8500
2026-05-03,Robot Phobo,Алматы,1,49000
Часть 1. Стандартный модуль csv
Чтение со словарями
import csv
with open('sales.csv', newline='', encoding='utf-8') as f:
reader = csv.DictReader(f)
for row in reader:
print(row['product'], '—', row['amount'])
Подсчёт суммы продаж
import csv
total = 0
with open('sales.csv', newline='', encoding='utf-8') as f:
reader = csv.DictReader(f)
for row in reader:
total += int(row['amount']) * int(row['price'])
print(f'Общая выручка: {total:,} тг')
Заметьте: значения из CSV всегда строки. Преобразование в число — на нас.
Группировка вручную
Кто больше всех продаёт по городам:
import csv
from collections import defaultdict
by_city = defaultdict(int)
with open('sales.csv', newline='', encoding='utf-8') as f:
for row in csv.DictReader(f):
by_city[row['city']] += int(row['amount']) * int(row['price'])
for city, total in sorted(by_city.items(), key=lambda x: -x[1]):
print(f'{city}: {total:,} тг')
Фильтр + запись в новый файл
import csv
with open('sales.csv', newline='', encoding='utf-8') as src, \
open('sales_almaty.csv', 'w', newline='', encoding='utf-8') as dst:
reader = csv.DictReader(src)
writer = csv.DictWriter(dst, fieldnames=reader.fieldnames)
writer.writeheader()
for row in reader:
if row['city'] == 'Алматы':
writer.writerow(row)
Часть 2. pandas — табличный подход
Установка:
pip install pandas
Чтение CSV в DataFrame
import pandas as pd
df = pd.read_csv('sales.csv')
print(df.head())
Вывод:
date product city amount price
0 2026-05-01 Arduino UNO Алматы 3 15000
1 2026-05-01 Robot Phobo Астана 1 49000
2 2026-05-02 Arduino UNO Шымкент 2 15000
3 2026-05-02 ESP32 Алматы 5 8500
4 2026-05-03 Robot Phobo Алматы 1 49000
pandas сам распознал заголовки и попытался угадать типы.
Полезные параметры read_csv
df = pd.read_csv(
'sales.csv',
sep=',', # разделитель
encoding='utf-8', # кодировка
parse_dates=['date'], # сразу превратить в datetime
dtype={'amount': int, 'price': int},
na_values=['', 'NA', 'NULL'], # что считать пропуском
thousands=' ', # для чисел вида "1 500 000"
)
Новая колонка
df['revenue'] = df['amount'] * df['price']
print(df[['product', 'revenue']])
Фильтрация
almaty = df[df['city'] == 'Алматы']
big = df[df['revenue'] > 30000]
Группировка и агрегаты
by_city = df.groupby('city')['revenue'].sum().sort_values(ascending=False)
print(by_city)
Вывод:
city
Алматы 135500
Астана 49000
Шымкент 30000
Name: revenue, dtype: int64
Сразу несколько метрик:
stats = df.groupby('product').agg(
sales=('amount', 'sum'),
revenue=('revenue', 'sum'),
avg_price=('price', 'mean'),
)
print(stats)
Запись CSV
df.to_csv('sales_with_revenue.csv', index=False, encoding='utf-8')
index=False — иначе pandas запишет номера строк отдельной колонкой.
Проблема: кодировка
Самая частая ошибка при работе с CSV — UnicodeDecodeError. Виноваты не вы,
виноват источник: Excel и российские госсайты часто отдают файлы в cp1251
или utf-8-sig (с BOM).
# Файл из Excel — почти всегда utf-8-sig или cp1251
df = pd.read_csv('export.csv', encoding='utf-8-sig')
df = pd.read_csv('export.csv', encoding='cp1251')
Подобрать вручную можно через библиотеку chardet:
# pip install chardet
import chardet
with open('mystery.csv', 'rb') as f:
raw = f.read(10000)
print(chardet.detect(raw))
# {'encoding': 'windows-1251', 'confidence': 0.98, ...}
Проблема: разделитель
Файлы из Excel в русской локали часто используют ; как разделитель.
df = pd.read_csv('export.csv', sep=';')
Если разделитель неизвестен — pandas может угадать (sep=None,
engine='python').
Проблема: большие файлы
Файл на 5 ГБ в память не лезет. Решения:
Чтение по частям:
import pandas as pd
total = 0
for chunk in pd.read_csv('huge.csv', chunksize=100_000):
total += chunk['amount'].sum()
print(total)
Только нужные колонки:
df = pd.read_csv('huge.csv', usecols=['date', 'amount'])
Подходящие типы данных:
df = pd.read_csv('huge.csv', dtype={'id': 'int32', 'flag': 'int8'})
Подводные камни
Предупреждение
Кодировка по умолчанию. Открывайте всегда с явной
encoding=.Числа как строки. В модуле
csvвсё строки. Вpandasтип зависит от содержимого — если в столбце вдруг попалась нечисловая ячейка, весь столбец станетobject.NaN-ы в pandas. Пустые ячейки превращаются в
NaN. Помните об этом при сравнениях:NaN == NaNэтоFalse.Excel и .csv. Excel при сохранении меняет кодировку, разделитель, может добавить BOM. Лучше попросить экспорт в
.xlsxи читатьpd.read_excel.Не парсите CSV руками через split(„,“). Внутри значений бывают запятые в кавычках — стандартный парсер их обработает, а ваш — нет.
Смотрите также
Модуль csv — работа с CSV-файлами в Python — справочник по модулю csv
Чтение CSV-файлов в Python — детально про чтение
Модуль json — работа с JSON в Python — JSON как альтернативный формат
Примечание
Лицензия и источники
Часть материала адаптирована из официальной документации Python (https://docs.python.org/3/library/csv.html) и документации проекта pandas (https://pandas.pydata.org/docs/, лицензия BSD-3). Документация Python распространяется под Python Software Foundation License Version 2 (PSF License). Адаптация, переработка, оригинальные примеры и пояснения — © AlashEd Wiki.