Подтвердить что ты не робот

Почему эта массив numpy слишком большой для загрузки?

У меня есть файл npz 3.374Gb, myfile.npz.

Я могу прочитать его и просмотреть имена файлов:

a = np.load('myfile.npz')
a.files

дает

['arr_1','arr_0']

Я могу читать в 'arr_1' ok

a1=a['arr_1']

Однако я не могу загрузить в arr_0 или прочитать его форму:

a1=a['arr_0']
a['arr_0'].shape

обе вышеперечисленные операции дают следующую ошибку:

ValueError: array is too big

У меня 16Gb RAM, из которых доступно 8.370Gb. Таким образом, проблема не связана с памятью. Мои вопросы:

  • Должен ли я прочитать этот файл?

  • Может ли кто-нибудь объяснить эту ошибку?

  • Я искал использование np.memmap, чтобы обойти это - это разумный подход?

  • Какой подход отладки следует использовать?

EDIT:

Я получил доступ к компьютеру с большим объемом оперативной памяти (48 ГБ) и загрузился. dtype был фактически complex128, а несжатая память a['arr_0'] составляла 5750784000 байт. Похоже, что накладные расходы RAM могут потребоваться. Либо это, либо мое предсказанное количество доступной ОЗУ было неправильным (я использовал WindowsSysinternals RAMmap).

4b9b3361

Ответ 1

Массив np.complex128 с размерами (200, 1440, 3, 13, 32) должен занимать около 5.35GiB без сжатия, поэтому, если у вас действительно есть 8,3 ГБ свободной адресной памяти, тогда в принципе вы должны иметь возможность загрузить массив.

Однако, основываясь на ваших ответах в комментариях ниже, вы используете 32-битные версии Python и numpy. В Windows 32-разрядный процесс может обрабатывать только до 2 ГБ памяти (или 4 ГБ, если бинарный файл был скомпилирован с флагом IMAGE_FILE_LARGE_ADDRESS_AWARE; 32-битных дистрибутивов Python нет). Следовательно, ваш процесс Python ограничен 2 ГБ адресного пространства, независимо от того, сколько у вас физической памяти.

Вы можете установить 64-битные версии Python, numpy и любых других библиотек Python, которые вам нужны, или жить с лимитом 2 ГБ и попытаться обойти его. В последнем случае вы можете избавиться от хранения массивов, которые превышают ограничение 2 ГБ в основном на диске (например, с помощью np.memmap), но я бы посоветовал вам перейти на вариант №1, поскольку операции с memmaped массивами намного медленнее в в большинстве случаев, чем для обычных np.array, которые полностью находятся в ОЗУ.


Если у вас уже есть другая машина с достаточным объемом ОЗУ для загрузки всего массива в память ядра, я бы предложил вам сохранить массив в другом формате (либо как обычный np.memmap, или, возможно, лучше, в файле HDF5, используя PyTables или H5py). Также возможно (хотя и немного сложнее) извлечь массив проблем из файла .npz, не загружая его в ОЗУ, чтобы затем открыть его как массив np.memmap, находящийся на диске:

import numpy as np

# some random sparse (compressible) data
x = np.random.RandomState(0).binomial(1, 0.25, (1000, 1000))

# save it as a compressed .npz file
np.savez_compressed('x_compressed.npz', x=x)

# now load it as a numpy.lib.npyio.NpzFile object
obj = np.load('x_compressed.npz')

# contains a list of the stored arrays in the format '<name>.npy'
namelist = obj.zip.namelist()

# extract 'x.npy' into the current directory
obj.zip.extract(namelist[0])

# now we can open the array as a memmap
x_memmap = np.load(namelist[0], mmap_mode='r+')

# check that x and x_memmap are identical
assert np.all(x == x_memmap[:])