Где будешь искать причину, если при объединении (merge/join) двух таблиц в Pandas возникает ошибка нехватки памяти?

«Где будешь искать причину, если при объединении (merge/join) двух таблиц в Pandas возникает ошибка нехватки памяти?» — вопрос из категории Pandas и NumPy, который задают на 26% собеседований Data Scientist / ML Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

При ошибке памяти при слиянии в Pandas я действую по следующему чек-листу, начиная с самых вероятных причин:

1. Анализ объема данных:

# Оцениваю реальный объем памяти, занимаемый DataFrame
print(f"df1: {df1.memory_usage(deep=True).sum() / 1024**2:.2f} MB")
print(f"df2: {df2.memory_usage(deep=True).sum() / 1024**2:.2f} MB")

# Смотрю размеры таблиц
print(f"df1 shape: {df1.shape}, df2 shape: {df2.shape}")

Если суммарный объем близок к доступной оперативной памяти — проблема очевидна.

2. Оптимизация типов данных: Часто в сырых данных используются неоптимальные типы, например, int64 или object для категориальных признаков.

# Привожу типы к более эффективным
df['category_col'] = df['category_col'].astype('category')
df['int_col'] = pd.to_numeric(df['int_col'], downcast='integer')
df['float_col'] = pd.to_numeric(df['float_col'], downcast='float')

3. Выбор стратегии слияния:

  • inner join создает наименьшую результирующую таблицу.
  • Если нужен outer join, иногда эффективнее сделать два inner запроса и затем конкатенировать результаты.

4. Проверка ключей слияния: Дубликаты в ключах могут взрывным образом увеличивать размер результата (декартово произведение).

# Проверяю на дубликаты ключей
print(f"Дубликаты в df1['key']: {df1['key'].duplicated().sum()}")
print(f"Дубликаты в df2['key']: {df2['key'].duplicated().sum()}")

5. Альтернативные подходы:

  • Итеративная обработка: Разбиваю одну из таблиц на чанки и делаю merge по частям.
  • Использование Dask: Если данные не помещаются в память, перехожу на библиотеку Dask для работы с ними на диске или в распределенной памяти.
  • Переход к СУБД: Для регулярных операций с большими объемами данных правильным решением является использование базы данных (например, PostgreSQL) и выполнение JOIN средствами SQL.