Python 3 MemoryError: Unable to allocate

На py 2 тот же скрипт работает: В системе стоит 16Гб используется 10ГБ.

При запуске скрипта на py 3.8 16Гб расходуются полностью и выдает ошибку:

MemoryError: Unable to allocate 481. MiB for an array with shape (12195, 5171) and data type float64

оба python 64-bit как это можно исправить?


Ответы (2 шт):

Автор решения: CrazyElf

Без кода советовать что-то сложно, но есть традиционно применяемые методы:

  • Понизить тип данных, например, вместо float64 использовать float32 или даже float16 (соответственно, понизив требования к памяти в 2 или в 4 раза), но это зависит от того, какая точность вычислений вам нужна. Для каких-то задач точность понижать нельзя, а для каких-то можно, а то и даже лучше результат с пониженной точностью получается (лучше генерализация).
  • Использовать разреженные матрицы scipy.sparse и те методы и библиотеки, которые умеют с ними работать. Если ваши данные по своей природе разреженные это может дать экономию памяти на порядок.
  • Если речь о машинном обучении, то зачастую бывает не обязательно обучаться сразу на всех данных, можно использовать случайные подмножества фич и случайное же сэмплирование наблюдений, а потом усреднить получающиеся результаты, сделав такие случайные выборки много раз. А бывает и так, что если данных у вас очень много и они сильно однородные, то и обучение всего на 1/10 случайно выбранных данных (через df.sample) даёт почти такое же качество, как и обучение на полном наборе данных, при этом обучение происходит гораздо быстрее, и можно успеть ещё и подобрать оптимальные параметры обучения, повысив качество.

Но и это не всё.

  • Некоторые библиотеки позволяют мапить массивы на файлы и не держать таким образом массивы в памяти.
  • Есть библиотеки, которые умеют сжимать массивы в памяти и при этом довольно прозрачно с ними работать как с обычными массивами.
  • Если вы работаете с Pandas, то есть такие библиотеки, как Dask и Vaex, которые имеют практически такой же интерфейс как Pandas, но при этом работают с файлами на диске, подтягивая данные в память по мере необходимости и оптимизируя запросы к данным, например, распараллеливая их.
→ Ссылка
Автор решения: Анна Лебедева

Подход @CrazyElf дал свои результаты. Понижение до float32 устранило проблемы с памятью. Также оказалось полезным знать размер датасетов. Это делается через: df.info(memory_usage='deep')

→ Ссылка