← Назад к вопросам
Что случится если обработать файл который не вмещается в память в 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 | Оптимизирован, быстро | Экосистема меньше |
| DuckDB | SQL удобен, быстро | Новый инструмент |
| Spark | Масштабируется | Оверхед, сложнее |
Мой выбор в production
- CSV < 1GB: обычный pd.read_csv()
- CSV 1-10GB: chunksize + обработка
- CSV > 10GB: Parquet + Polars или DuckDB
- CSV > 1TB: Spark
Вывод
Pandas не предназначена для обработки файлов больше доступной памяти. Три варианта:
- Используй chunks для итеративной обработки
- Конвертируй в Parquet/HDF5
- Переходи на Polars или DuckDB
Важно: план обработки больших данных нужно делать с начала проекта, не в конце!