Как я могу отслеживать и отображать постоянные изменения, внесенные в файл HDF5, с помощью python

#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())
 

Чтобы продемонстрировать, я добавил эти строки в ваш код вместе с несколькими другими изменениями для решения следующих проблем:

  1. Исправьте ошибки, отмеченные в моих комментариях (я добавил create_array() их для первоначального создания файла и набора данных. Я создал его как набор данных с изменяемым размером, чтобы упростить логику update_array() .
  2. Я изменил update_array() код, чтобы увеличить набор данных и добавить новое значение. Это намного чище (и быстрее), чем ваш 4-этапный процесс.
  3. Я использовал with / as: контекстный менеджер Python, чтобы открыть файл. Это устраняет необходимость в его закрытии и (что более важно) гарантирует, что он будет закрыт чисто, если программа выйдет неправильно.
  4. Я удалил функции NumPy. Нет необходимости создавать массив, если вы каждый раз добавляете 1 скаляр.
  5. Моя инструкция по печати показывает предпочтительный метод создания массива NumPy из набора данных. Используйте hf['array'][:] вместо np.array(hf.get('array')) .
  6. Я предпочитаю открывать файлы один раз (если только нет веской причины для открытия и закрытия). Это устраняет накладные расходы на установку/удаление файлов. Я этого не делал. Если вы хотите, переместите 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. Спасибо, приятель, за твой вклад в это дело. Это именно то, чему я хотел подражать в своем подходе.