Я экспериментирую с трехмерным массивом zarr, хранящимся на диске:
Name: /data
Type: zarr.core.Array
Data type: int16
Shape: (102174, 1100, 900)
Chunk shape: (12, 220, 180)
Order: C
Read-only: True
Compressor: Blosc(cname='zstd', clevel=3, shuffle=BITSHUFFLE, blocksize=0)
Store type: zarr.storage.DirectoryStore
No. bytes: 202304520000 (188.4G)
No. bytes stored: 12224487305 (11.4G)
Storage ratio: 16.5
Chunks initialized: 212875/212875
Насколько я понимаю, массивы zarr также могут находиться в памяти - сжаты, как если бы они находились на диске,Поэтому я подумал, почему бы не попробовать загрузить все это в ОЗУ на машине с 32 ГБ памяти. Сжатый , для набора данных потребуется приблизительно 50% ОЗУ .В несжатом виде потребовалось бы примерно в 6 раз больше оперативной памяти, чем доступно.
Подготовка:
import os
import zarr
from numcodecs import Blosc
import tqdm
zpath = '...' # path to zarr data folder
disk_array = zarr.open(zpath, mode = 'r')['data']
c = Blosc(cname = 'zstd', clevel=3, shuffle = Blosc.BITSHUFFLE)
memory_array = zarr.zeros(
disk_array.shape, chunks = disk_array.chunks,
dtype = disk_array.dtype, compressor = c
)
Следующий эксперимент почти сразу завершился неудачей с ошибкой нехватки памяти:
memory_array[:, :, :] = disk_array[:, :, :]
Насколько я понимаю, disk_array[:, :, :]
попытается создать несжатый полноразмерный массив с нулевыми значениями, который, очевидно, потерпит неудачу.
Вторая попытка, которая работает, но мучительно медленная:
chunk_lines = disk_array.chunks[0]
chunk_number = disk_array.shape[0] // disk_array.chunks[0]
chunk_remain = disk_array.shape[0] % disk_array.chunks[0] # unhandled ...
for chunk in tqdm.trange(chunk_number):
chunk_slice = slice(chunk * chunk_lines, (chunk + 1) * chunk_lines)
memory_array[chunk_slice, :, :] = disk_array[chunk_slice, :, :]
Здесь я пытаюсь прочитать определенное количество порций за раз и поместить их в мой массив в памяти. Это работает, но это примерно в 6-7 раз медленнее, чем то, что требовалось для записи этой вещи на диск. РЕДАКТИРОВАТЬ: Да, это все еще медленно, но 6-7 раз происходило из-запроблема с диском.
Какой разумный и быстрый способ добиться этого?Я предполагаю, что помимо неправильного подхода мои чанки также могут быть слишком маленькими - но я не уверен.
РЕДАКТИРОВАТЬ: форма, размер чанка и сжатие должны быть одинаковыми для дискамассив и массив в памяти.Следовательно, должна быть возможность исключить процедуру распаковки-сжатия в моем примере выше.
Я обнаружил zarr.convenience.copy
, но он помечен как experimental feature
, подлежит дальнейшему изменению.
Проблема, связанная с GitHub