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')