КПКейсПрактика
Все материалы
Продуктовая аналитикапрактикумсредний

Как ускорить pandas: память, типы и обработка больших файлов

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

КПКейсПрактика8 августа 2026 г.12 мин
Два аналитика уменьшают размер таблицы pandas и обрабатывают большой поток данных частями.

Большой CSV начинает медленно открываться, ноутбук съедает всю память, а простая группировка занимает минуты. Первая реакция — переписать всё на другой инструмент. Но часто проблема проще: pandas читает лишние колонки, хранит категории как длинные строки и создаёт несколько копий DataFrame.

Коротко

Оптимизация начинается с измерения: сколько строк, колонок и памяти занимает таблица. Затем уменьши вход — выбери поля и период, задай типы, переведи повторяющиеся категории в `category`, а большой файл обрабатывай кусками или в Parquet.

  • Не загружай в память поля, которые не участвуют в расчёте.
  • Сначала проверь `memory_usage`, потом меняй dtype.
  • При chunking агрегируй каждый кусок и объединяй маленькие результаты.
  • Не делай `.copy()` и `.merge()` для огромной таблицы без необходимости.

Узнай, что занимает память

Размер файла на диске не равен размеру DataFrame в памяти. Строки и object-колонки часто занимают больше, чем ожидается. Профиль по колонкам помогает найти главный источник расхода, а не оптимизировать случайное поле.

pythonПрофиль памяти по колонкам
memory = (
    orders.memory_usage(deep=True)
    .sort_values(ascending=False)
)
print(memory)
print('total MB:', memory.sum() / 1024**2)

Выбери колонки и типы до чтения

Если отчёт использует пять полей, не загружай пятьдесят. Для целых чисел укажи подходящий тип, а повторяющиеся строки переведи в category. Это не универсальное правило: сначала убедись, что диапазон значений помещается в выбранный dtype и что категория не содержит почти уникальную строку на каждую запись.

pythonЧитать только нужное и уменьшить повторяющиеся категории
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` по средним кускам может быть неверным; для среднего сохраняй сумму и количество.

pythonСумма и количество по каналам без загрузки всего файла
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 не исправляет неверное зерно и не заменяет контроль источника.

pythonСохранить подготовленный слой в Parquet
orders.to_parquet('data/clean/orders.parquet', index=False)

report = pd.read_parquet(
    'data/clean/orders.parquet',
    columns=['created_at', 'channel', 'revenue'],
)
Продолжить чтение
Вся библиотека