Добавочные записи в hdf5 с h5py
У меня есть вопрос о том, как лучше всего писать в hdf5 файлы с помощью python/h5py.
У меня есть такие данные, как:
-----------------------------------------
| timepoint | voltage1 | voltage2 | ...
-----------------------------------------
| 178 | 10 | 12 | ...
-----------------------------------------
| 179 | 12 | 11 | ...
-----------------------------------------
| 185 | 9 | 12 | ...
-----------------------------------------
| 187 | 15 | 12 | ...
...
с около 10 ^ 4 столбцами и около 10 ^ 7 строк. (Это около 10 ^ 11 (100 миллиардов) элементов, или ~ 100 ГБ с 1 байтами).
С этими данными типичное использование - это в большинстве случаев однократная запись, многократное чтение, и типичным случаем чтения будет захват столбца 1 и другого столбца (скажем, 254), загрузка обоих столбцов в память и выполнение какой-то интересной статистики.
Я думаю, что хорошая структура hdf5 должна состоять в том, чтобы каждый столбец в таблице выше был группой hdf5, что привело бы к 10 ^ 4 группам. Таким образом, нам не нужно будет читать все данные в память, да? Однако структура hdf5 еще не определена, поэтому она может быть чем угодно.
Теперь вопрос:
Я получаю данные ~ 10 ^ 4 строки за раз (и каждый раз не одно и то же число строк), и мне нужно записать их постепенно в файл hdf5. Как мне написать этот файл?
Я рассматриваю python и h5py, но могу порекомендовать другой инструмент. Пробивает путь, например,
dset = f.create_dataset("voltage284", (100000,), maxshape=(None,), dtype='i8', chunks=(10000,))
а затем, когда прибудет еще один блок из 10 ^ 4 строк, заменить набор данных?
Или лучше просто хранить каждый блок из 10 ^ 4 строк в виде отдельного набора данных? Или мне действительно нужно знать окончательное количество строк? (Это будет сложно получить, но, возможно, возможно).
Я могу взять залог за hdf5, если он тоже не подходит для работы, хотя я думаю, что, как только неловкие записи будут сделаны, это будет замечательно.
Ответы
Ответ 1
В разделе FAQ вы можете расширить набор данных с помощью dset.resize
. Например,
import os
import h5py
import numpy as np
path = '/tmp/out.h5'
os.remove(path)
with h5py.File(path, "a") as f:
dset = f.create_dataset('voltage284', (10**5,), maxshape=(None,),
dtype='i8', chunks=(10**4,))
dset[:] = np.random.random(dset.shape)
print(dset.shape)
# (100000,)
for i in range(3):
dset.resize(dset.shape[0]+10**4, axis=0)
dset[-10**4:] = np.random.random(10**4)
print(dset.shape)
# (110000,)
# (120000,)
# (130000,)
Ответ 2
Как отметил @unutbu, dset.resize
- отличный вариант. Возможно, вам покажется pandas
и его поддержка HDF5 полезной, учитывая ваш рабочий процесс. Похоже, что HDF5 - разумный выбор, учитывая ваши потребности, но возможно, что ваша проблема может быть выражена лучше с помощью дополнительного слоя сверху.
Одной из важных вещей является ориентация данных. Если вас в первую очередь интересуют операции чтения, и вы в основном выбираете данные по столбцам, то, похоже, вы захотите транспонировать данные таким образом, чтобы чтения могли происходить по строкам, поскольку HDF5 хранит их в порядке следования строк.