← Назад к вопросам

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

2.0 Middle🔥 121 комментариев
#Pandas и обработка данных

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Обработка больших файлов в Pandas: MemoryError

Что происходит?

Когда вы пытаетесь загрузить файл больше, чем доступная RAM:

import pandas as pd

df = pd.read_csv("huge_file_50gb.csv")  # Если RAM < 50GB
# MemoryError: Unable to allocate 15.0 GB for an array with shape (2000000000,) and data type float64

Процесс просто падает с MemoryError. Pandas загружает весь файл в память как единый объект.

Решение 1: Читай чанками (chunks)

Это самый практичный подход:

# Читаем по 50000 строк за раз
chunk_size = 50000
chunks = []

for chunk in pd.read_csv("huge_file.csv", chunksize=chunk_size):
    # Обрабатываем каждый чанк отдельно
    processed = chunk[chunk["value"] > 100]
    chunks.append(processed)

# Объединяем только результаты
result = pd.concat(chunks, ignore_index=True)

Преимущества:

  • Гарантирует работу с любым размером файла
  • Контролируешь использование памяти
  • Просто реализуется

Решение 2: Фильтрация при загрузке

Загрузи только нужные столбцы и строки:

# Берем только нужные столбцы
df = pd.read_csv(
    "huge_file.csv",
    usecols=["user_id", "amount", "date"],  # Не все столбцы!
    nrows=1000000  # Ограничиваем строки
)

Решение 3: Используй более эффективные форматы

Parquet — намного быстрее и меньше, чем CSV:

# Один раз конвертируем CSV в Parquet
for chunk in pd.read_csv("huge_file.csv", chunksize=50000):
    chunk.to_parquet("output.parquet", append=True)

# Потом читаем эффективно
df = pd.read_parquet("output.parquet")  # Намного быстрее!

HDF5 для структурированных данных:

df.to_hdf("data.h5", key="data", mode="w", complevel=9)  # Сжатие
df = pd.read_hdf("data.h5", key="data")  # Быстро

Решение 4: Специализированные библиотеки

Polars — быстрее Pandas, меньше памяти:

import polars as pl

# Polars ленивы по умолчанию и оптимизируют запросы
df = pl.scan_csv("huge_file.csv")
    .filter(pl.col("value") > 100)
    .select(["user_id", "amount"])
    .collect()  # Выполнить запрос

DuckDB — SQL для больших файлов:

import duckdb

# DuckDB читает только нужные данные
result = duckdb.query("""
    SELECT user_id, SUM(amount) as total
    FROM 'huge_file.csv'
    WHERE value > 100
    GROUP BY user_id
""").to_df()

Решение 5: Распределенная обработка

Spark для очень больших датасетов:

from pyspark.sql import SparkSession

spark = SparkSession.builder.appName("BigData").getOrCreate()

df = spark.read.csv("huge_file.csv", header=True)
df.filter(df.value > 100).groupBy("user_id").count().show()

Пример: реальный workflow

import pandas as pd
import numpy as np

# Файл 50GB, RAM 16GB
chunk_size = 100000
results = []

for i, chunk in enumerate(pd.read_csv("sales_data.csv", chunksize=chunk_size)):
    # Фильтруем
    chunk = chunk[chunk["price"] > 0]
    
    # Агрегируем
    daily_sales = chunk.groupby("date")["price"].sum()
    results.append(daily_sales)
    
    # Контролируем память
    if i % 10 == 0:
        print(f"Обработано {i * chunk_size} строк")

# Объединяем результаты
final_result = pd.concat(results).groupby(level=0).sum()

Сравнение подходов

ПодходПреимуществаНедостатки
ChunksПросто, встроеноМедленнее для сложных операций
ParquetБыстро, эффективноНужно конвертировать один раз
PolarsОптимизирован, быстроЭкосистема меньше
DuckDBSQL удобен, быстроНовый инструмент
SparkМасштабируетсяОверхед, сложнее

Мой выбор в production

  1. CSV < 1GB: обычный pd.read_csv()
  2. CSV 1-10GB: chunksize + обработка
  3. CSV > 10GB: Parquet + Polars или DuckDB
  4. CSV > 1TB: Spark

Вывод

Pandas не предназначена для обработки файлов больше доступной памяти. Три варианта:

  • Используй chunks для итеративной обработки
  • Конвертируй в Parquet/HDF5
  • Переходи на Polars или DuckDB

Важно: план обработки больших данных нужно делать с начала проекта, не в конце!