#python #file #filesystems #hdf5 #hdfstore
Вопрос:
У меня есть эта функция, которая постоянно добавляет новый элемент в массив данных файла HDF5 каждую секунду.
from time import time, sleep
i = 100
def update_array():
hf = h5py.File('task1.h5', 'r ')
old_rec = np.array(hf.get('array'))
global i
i = i 1
new_rec = np.append(old_rec, i)
#deleting old record andreplacing with updated record
del hf['array']
new_data = hf.create_dataset('array', data = new_rec)
print(new_rec)
hf.close()
while True:
sleep(1 - time() % 1)
update_array()
Вывод строки печати (в основном показывает обновленный массив….. мы не знаем, сохраняется ли он в файле или нет):
[101.]
[101. 102.]
[101. 102. 103.]
[101. 102. 103. 104.]
[101. 102. 103. 104. 105.]
[101. 102. 103. 104. 105. 106.]
[101. 102. 103. 104. 105. 106. 107.]
[101. 102. 103. 104. 105. 106. 107. 108.]
Я хочу иметь отдельный блокнот, который может отслеживать изменения, внесенные вышеуказанной функцией, и отображать обновленное содержимое этого набора данных, присутствующего в файловой системе HDF5.
Мне нужна отдельная функция для этой задачи, потому что я хочу убедиться, что обновленный контент сохраняется в файлах HDF5, и выполнять дальнейшие операции с ними по мере их поступления.
Комментарии:
1. Работает ли этот код для вас? Когда я запускаю, я получаю несколько ошибок: 1)
h5py.File('task1.h5', 'r ')
выдает ошибку при первом цикле b/c, файл не существует; 2) когда я меняю режим файла на'a'
, я получаю ошибку приold_rec = np.array(hf.get('array'))
b/c'array'
, набор данных не существует. Такжеwhile True
запуски навсегда — когда вы запускаете, вы убиваете его в командной строке? Я могу исправить эти ошибки, но хотел бы убедиться, прежде чем это сделаю.2. Зачем вам нужен отдельный файл журнала? Файл HDF5 является «самоописанием» и может быть опрошен. Таким образом, вы можете просто проверить набор данных, чтобы проверить, были ли записаны данные.
Ответ №1:
Вот потенциальное решение, связывающее атрибуты с 'array'
набором данных. Добавление атрибутов к объекту данных HDF5 очень просто .attrs
. Он имеет синтаксис, подобный словарю: h5obj[attr_name] = attr_value
. Типами значений атрибутов могут быть int, строки, значения с плавающей точкой и массивы. Вы можете добавить 2 атрибута в свой набор данных со следующими 2 строками:
hf['array'].attrs['Last Value'] = i
hf['array'].attrs['Time Added'] = ctime(time())
Чтобы продемонстрировать, я добавил эти строки в ваш код вместе с несколькими другими изменениями для решения следующих проблем:
- Исправьте ошибки, отмеченные в моих комментариях (я добавил
create_array()
их для первоначального создания файла и набора данных. Я создал его как набор данных с изменяемым размером, чтобы упростить логикуupdate_array()
. - Я изменил
update_array()
код, чтобы увеличить набор данных и добавить новое значение. Это намного чище (и быстрее), чем ваш 4-этапный процесс. - Я использовал
with / as:
контекстный менеджер Python, чтобы открыть файл. Это устраняет необходимость в его закрытии и (что более важно) гарантирует, что он будет закрыт чисто, если программа выйдет неправильно. - Я удалил функции NumPy. Нет необходимости создавать массив, если вы каждый раз добавляете 1 скаляр.
- Моя инструкция по печати показывает предпочтительный метод создания массива NumPy из набора данных. Используйте
hf['array'][:]
вместоnp.array(hf.get('array'))
. - Я предпочитаю открывать файлы один раз (если только нет веской причины для открытия и закрытия). Это устраняет накладные расходы на установку/удаление файлов. Я этого не делал. Если вы хотите, переместите
with / as:
строки в основную и передайте полученныйhf
объектcreate_array()
update_array()
функциям и. Если вы сделаете это, вы сможете легко объединить 2 функции. (Вам понадобится логика, чтобы проверить'array'
, существует ли набор данных.)
Код ниже:
import h5py
from time import time, sleep, ctime
def create_array():
with h5py.File('task1.h5', 'w') as hf:
global i
#create dataset and add new record
new_data = hf.create_dataset('array', shape=(1,), maxshape=(None,),
data = [i])
# add attributes
hf['array'].attrs['Last Value'] = i
hf['array'].attrs['Time Added'] = ctime(time())
print(hf['array'][:])
def update_array():
with h5py.File('task1.h5', 'r ') as hf:
global i
i = 1
#resize dataset and add new record
a0 = hf['array'].shape[0]
hf['array'].resize(a0 1,axis=0)
hf['array'][a0] = i
# add attributes
hf['array'].attrs['Last Value'] = i
hf['array'].attrs['Time Added'] = ctime(time())
print(hf['array'][:])
i = 100
create_array()
while i < 110:
sleep(1 - time() % 1)
update_array()
print('Done')
Комментарии:
1. Спасибо, приятель, за твой вклад в это дело. Это именно то, чему я хотел подражать в своем подходе.