Как ускорить pandas: память, типы и обработка больших файлов
Что делать, если pandas медленно работает или не помещает файл в память: категории, downcast, chunksize, Parquet и контроль размера данных.

Большой CSV начинает медленно открываться, ноутбук съедает всю память, а простая группировка занимает минуты. Первая реакция — переписать всё на другой инструмент. Но часто проблема проще: pandas читает лишние колонки, хранит категории как длинные строки и создаёт несколько копий DataFrame.
Коротко
Оптимизация начинается с измерения: сколько строк, колонок и памяти занимает таблица. Затем уменьши вход — выбери поля и период, задай типы, переведи повторяющиеся категории в `category`, а большой файл обрабатывай кусками или в Parquet.
- Не загружай в память поля, которые не участвуют в расчёте.
- Сначала проверь `memory_usage`, потом меняй dtype.
- При chunking агрегируй каждый кусок и объединяй маленькие результаты.
- Не делай `.copy()` и `.merge()` для огромной таблицы без необходимости.
Узнай, что занимает память
Размер файла на диске не равен размеру DataFrame в памяти. Строки и object-колонки часто занимают больше, чем ожидается. Профиль по колонкам помогает найти главный источник расхода, а не оптимизировать случайное поле.
memory = (
orders.memory_usage(deep=True)
.sort_values(ascending=False)
)
print(memory)
print('total MB:', memory.sum() / 1024**2)Выбери колонки и типы до чтения
Если отчёт использует пять полей, не загружай пятьдесят. Для целых чисел укажи подходящий тип, а повторяющиеся строки переведи в category. Это не универсальное правило: сначала убедись, что диапазон значений помещается в выбранный dtype и что категория не содержит почти уникальную строку на каждую запись.
orders = pd.read_csv(
'data/orders.csv',
usecols=['order_id', 'created_at', 'channel', 'revenue'],
dtype={'order_id': 'int32', 'channel': 'category'},
parse_dates=['created_at'],
)
orders['revenue'] = pd.to_numeric(orders['revenue'], downcast='float')Большой CSV обрабатывай частями
`chunksize` возвращает итератор DataFrame. Не нужно складывать все куски в список: посчитай агрегат внутри цикла и объедини небольшие результаты. Важно помнить, что `mean` по средним кускам может быть неверным; для среднего сохраняй сумму и количество.
parts = []
for chunk in pd.read_csv('data/orders.csv', chunksize=100_000):
part = (
chunk.groupby('channel', as_index=False)
.agg(revenue=('revenue', 'sum'), orders=('order_id', 'nunique'))
)
parts.append(part)
report = (
pd.concat(parts)
.groupby('channel', as_index=False)
.sum()
)Суммы и количества можно складывать по кускам. Уникальных пользователей нельзя просто суммировать: один user_id может попасть в несколько chunks. Для точного результата используй другое хранилище или сохраняй множество ключей, если оно помещается в память.
Parquet для повторных чтений
Если один и тот же CSV читается много раз, преобразуй его в Parquet после первичной очистки. Колонночный формат хранит типы, читает только нужные поля и обычно быстрее подходит для аналитических выборок. Но Parquet не исправляет неверное зерно и не заменяет контроль источника.
orders.to_parquet('data/clean/orders.parquet', index=False)
report = pd.read_parquet(
'data/clean/orders.parquet',
columns=['created_at', 'channel', 'revenue'],
)Материалы по теме
Как тестировать аналитические расчёты на Python и pandas
Практический гайд по тестам для аналитика: проверить метрики на маленьком датасете, поймать регрессию и защитить расчёт от тихих изменений.
Читать материал
Pandas apply и векторизация: как писать быстрее и понятнее
Когда использовать apply, почему векторные операции быстрее и как переписать медленный построчный расчёт в pandas.
Читать материал
Как загружать Excel, JSON и Parquet в pandas
Практический разбор источников в pandas: прочитать Excel и JSON, выбрать лист, сохранить типы и перейти с CSV на Parquet без сюрпризов.
Читать материал