Что произойдёт, если попытаться обработать в pandas файл, который не помещается в оперативную память?

«Что произойдёт, если попытаться обработать в pandas файл, который не помещается в оперативную память?» — вопрос из категории Pandas и NumPy, который задают на 26% собеседований Data Scientist / ML Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

При вызове pd.read_csv('huge_file.csv') pandas попытается загрузить весь датафрейм в оперативную память (RAM). Если файл превышает доступный объём памяти, это вызовет ошибку MemoryError и скрипт упадёт.

Стратегии обработки больших данных в pandas-стиле:

  1. Чтение по частям (Chunking): Самый распространённый метод. Файл считывается и обрабатывается порциями.

    import pandas as pd
    
    chunk_size = 50_000  # Количество строк в чанке
    chunk_iterator = pd.read_csv('huge_file.csv', chunksize=chunk_size)
    
    aggregated_results = []
    for chunk in chunk_iterator:
        # Обрабатываем каждый чанк независимо (фильтрация, агрегация)
        processed_chunk = chunk[chunk['value'] > 100].groupby('category').sum()
        aggregated_results.append(processed_chunk)
    
    # Объединяем финальные результаты (они должны быть небольшими)
    final_df = pd.concat(aggregated_results)
  2. Оптимизация типов данных: При загрузке сразу уменьшайте потребление памяти.

    dtypes = {'user_id': 'int32', 'category': 'category', 'price': 'float32'}
    df = pd.read_csv('file.csv', dtype=dtypes, usecols=['user_id', 'category', 'price'])
  3. Использование эффективных форматов хранения: Конвертация в бинарные форматы, которые быстрее читаются и часто занимают меньше места.

    # После обработки сохранить в Parquet или Feather
    df.to_parquet('data.parquet', compression='snappy')
    # Загрузка будет быстрее и может потребовать меньше памяти.
    df = pd.read_parquet('data.parquet')
  4. Использование Dask или Vaex: Для работы с данными, превышающими размер RAM, используйте библиотеки с похожим на pandas API, но работающие с данными на диске или распределённо.