Быстрый и эффективный способ сериализации и извлечения большого количества пустых массивов из файла HDF5 - PullRequest
0 голосов
/ 27 октября 2018

У меня есть огромный список массивов, в частности 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 ]

0 голосов
/ 28 октября 2018

Согласно 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] подмассивы этого большого набора данных.

Возможно, вы захотите поэкспериментировать с записью и чтением небольших наборов данных, если работа с этим большим набором слишком запутанная.

0 голосов
/ 27 октября 2018

Одним из способов было бы поместить каждую выборку в отдельную группу и индексировать непосредственно в нее. Я думаю, что преобразование занимает много времени, потому что он пытается загрузить весь набор данных в список (который он должен прочитать с диска). Реорганизовать файл h5 так, чтобы

  • группа
    • образец
      • 36 х 2048 может помочь в индексации скорости.
...