Почему я получаю OverflowError и WindowsError с numpy memmap и как ее решить?

Что касается другого моего вопроса здесь, этот код работает, если я использую небольшой кусок моего набора данных с dtype='int32', используя float64 выдает ошибку TypeError в моем основном процессе после этой части из-за safe правила, поэтому я буду придерживаться работы с int32 но тем не менее мне любопытно и я хочу знать об ошибках, которые я получаю.

fp = np.memmap("E:/TDM-memmap.txt", dtype='int32', mode='w+', shape=(len(documents), len(vocabulary)))
matrix = np.genfromtxt("Results/TDM-short.csv", dtype='int32', delimiter=',', skip_header=1)
fp[:] = matrix[:]

Если я использую полные данные (где shape=(329568, 27519)), с этими dtypes:

Я получаю OverflowError, когда использую int32 или int

а также

Я получаю WindowsError при использовании float64

Почему и как я могу это исправить?

Изменить: добавлены трассировки

Traceback для int32

Traceback (most recent call last):
File "C:/Users/zeferinix/PycharmProjects/Projects/NLP Scripts/NEW/LDA_Experimental1.py", line 123, in <module>
    fp = np.memmap("E:/TDM-memmap.txt", dtype='int32', mode='w+', shape=(len(documents), len(vocabulary)))
File "C:\Python27\lib\site-packages\numpy\core\memmap.py", line 260, in __new__
    mm = mmap.mmap(fid.fileno(), bytes, access=acc, offset=start)
WindowsError: [Error 8] Not enough storage is available to process this command

Traceback для float64

Traceback (most recent call last):
File "C:/Users/zeferinix/PycharmProjects/Projects/NLP Scripts/NEW/LDA_Experimental1.py", line 123, in <module>
    fp = np.memmap("E:/TDM-memmap.txt", dtype='float64', mode='w+', shape=(len(documents), len(vocabulary)))
File "C:\Python27\lib\site-packages\numpy\core\memmap.py", line 260, in __new__
    mm = mmap.mmap(fid.fileno(), bytes, access=acc, offset=start)
OverflowError: cannot fit 'long' into an index-sized integer

Редактировать: Добавлена ​​другая информация

Другая информация, которая может помочь: у меня есть жесткий диск объемом 1 ТБ (931 ГБ) с 2 разделами, диск D (22,8 ГБ без 150 ГБ), где мои рабочие файлы включают в себя этот сценарий, и где будет записываться memmap, и диск E (406 ГБ бесплатно) из 781GB), где мой торрент материал идет. Сначала я попытался записать файл mmap на диск D, и он сгенерировал 1 903 283 КБ для int32 и 3 806 566 КБ для float64. Я подумал, может быть, потому что у него не хватает места, поэтому я получаю эти ошибки, поэтому я попробовал диск E, которого должно быть более чем достаточно, но он сгенерировал тот же размер файла и выдал ту же ошибку.

1 ответ

Решение

Я не думаю, что можно генерировать np.memmap файл большого размера, используя 32-битную сборку NumPy, независимо от того, сколько места на диске у вас есть.

Ошибка возникает, когда np.memmap пытается позвонить mmap.mmap внутренне. Второй аргумент mmap.mmap указывает длину файла в байтах. Для массива 329568 на 27519, содержащего 64-битные (8-байтовые) значения, длина будет 72555054336 байт (т.е. ~72 ГБ).

Значение 72555054336 необходимо преобразовать в целочисленный тип, который можно использовать в качестве индекса. В 32-битном Python индексы должны быть 32-битными целочисленными значениями. Однако наибольшее число, которое может быть представлено 32-разрядным целым числом, намного меньше, чем 72555054336:

print(np.iinfo(np.int32(1)).max)
# 2147483647

Даже для 32-битного массива потребуется длина 36277527168 байт, что все еще примерно в 16 раз больше, чем наибольшее представимое 32-битное целое число.

Я не вижу простого способа обойти эту проблему, кроме перехода на 64-битный Python / Numpy. Для этого есть и другие веские причины - 32-битный Python может адресовать максимум 3 ГБ ОЗУ, даже если на вашей машине доступно 8 ГБ.


Даже если бы вы могли генерировать np.memmap такой большой, следующая строка

matrix = np.genfromtxt("Results/TDM-short.csv", dtype='int32', delimiter=',', skip_header=1)

определенно потерпит неудачу, поскольку требует создания массива в оперативной памяти размером 32 ГБ. Единственный способ, которым вы могли бы прочитать этот CSV-файл, - это небольшие фрагменты, как в моем ответе, на который я ссылался в комментариях выше.

Как я уже упоминал в комментариях к вашему другому вопросу, вам нужно конвертировать ваши TermDocumentMatrix к scipy.sparse матрица, а не запись в файл CSV. Это потребует намного, намного меньше места для хранения и оперативной памяти, так как может использовать тот факт, что почти все слова имеют нулевое значение.

Другие вопросы по тегам