Эффективный способ сериализации и извлечения большого количества массивов
У меня огромный список, в частности 113287
, из числа массивов, где каждый массив имеет форму 36 x 2048
, С точки зрения памяти это составляет 32 гигабайта.
На данный момент я сериализовал эти массивы в виде файла HDF5. Проблема в том, что извлечение отдельных массивов из этого файла hdf5 занимает мучительно много времени (к северу от 10 минут) для каждого доступа.
Как я могу ускорить это? Это очень важно для моей реализации, так как мне приходится несколько тысяч раз индексировать этот список для подачи в глубокие нейронные сети.
Вот как я индексирую в файл hdf5:
In [1]: import h5py
In [2]: hf = h5py.File('train_ids.hdf5', 'r')
In [5]: list(hf.keys())[0]
Out[5]: 'img_feats'
In [6]: group_key = list(hf.keys())[0]
In [7]: hf[group_key]
Out[7]: <HDF5 dataset "img_feats": shape (113287, 36, 2048), type "<f4">
# this is where it takes very very long time
In [8]: list(hf[group_key])[-1].shape
Out[8]: (36, 2048)
Есть идеи, где я могу ускорить процесс? Есть ли другой способ сериализации этих массивов для более быстрого доступа?
Примечание: я использую список Python, так как я хочу, чтобы порядок был сохранен (то есть, чтобы получить в том же порядке, в котором я его разместил при создании файла hdf5)
2 ответа
В соответствии с Out[7]
, "img_feats" - большой трехмерный массив. (113287, 36, 2048) форма.
определять ds
как набор данных (ничего не загружается):
ds = hf[group_key]
x = ds[0] # should be a (36, 2048) array
arr = ds[:] # should load the whole dataset into memory.
arr = ds[:n] # load a subset, slice
По данным h5py-чтение-запись-данные:
Наборы данных HDF5 повторно используют синтаксис NumPy для чтения и записи в файл. Спецификации срезов переводятся непосредственно в выборки "HyperSlab" HDF5 и являются быстрым и эффективным способом доступа к данным в файле.
Я не вижу смысла оборачивать это в list()
; то есть, разбивая трехмерный массив на список из 113287 двумерных массивов. Существует четкое сопоставление между наборами данных 3D в файле HDF5 и numpy
массивы.
h5py-fancy-indexing предупреждает, что необычная индексация набора данных идет медленнее. То есть, пытаясь загрузить, скажем, [1, 1000, 3000, 6000] подмассивы этого большого набора данных.
Возможно, вы захотите поэкспериментировать с написанием и чтением небольших наборов данных, если работа с таким большим набором слишком запутана.
Одним из способов было бы поместить каждую выборку в отдельную группу и индексировать непосредственно в нее. Я думаю, что преобразование занимает много времени, потому что он пытается загрузить весь набор данных в список (который он должен прочитать с диска). Реорганизовать файл h5 так, чтобы
- группа
- образец
- 36 х 2048 может помочь в индексации скорости.
- образец