如何在 python 的帮助下跟踪和显示 HDF5 文件中所做的不断变化

Posted

技术标签:

【中文标题】如何在 python 的帮助下跟踪和显示 HDF5 文件中所做的不断变化【英文标题】:How can I track and display constant changes made in an HDF5 file with the help of python 【发布时间】:2021-10-16 13:52:42 【问题描述】:

我有这个函数,它每秒不断地在 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)h5py.File('task1.h5', 'r+') 在第一个循环 b/c 上抛出错误文件不存在; 2) 当我将文件模式更改为'a' 时,old_rec = np.array(hf.get('array')) b/c 出现错误,'array' 数据集不存在。 while True 也永远运行 - 当你运行时你会在命令行中杀死它吗?我可以修复这些错误,但我想在此之前确认一下。 为什么要单独的日志文件? HDF5 文件是“自我描述的”并且可以被查询。因此,您可以简单地检查数据集以查看数据是否已写入。 【参考方案1】:

这是一个将属性附加到'array' 数据集的潜在解决方案。使用.attrs 可以轻松地将属性添加到 HDF5 数据对象。它具有类似字典的语法:h5obj[attr_name] = attr_value。属性值类型可以是整数、字符串、浮点数和数组。您可以使用以下 2 行向数据集添加 2 个属性:

hf['array'].attrs['Last Value'] = i
hf['array'].attrs['Time Added'] = ctime(time())

为了演示,我将这些行添加到您的代码中,并进行了一些其他修改以解决以下问题:

    更正我的 cmets 中记录的错误(我添加了 create_array() 以最初创建文件和数据集。我将其创建为 可调整大小 数据集以简化 update_array() 中的逻辑。 我修改了update_array() 代码以扩大数据集并附加新值。这比您的 4 步流程更简洁(也更快)。 我使用 Python 的 with / as: 上下文管理器打开文件。这消除了关闭它的需要,并且(更重要的是)确保在程序异常退出时干净地关闭它。 我删除了 NumPy 函数。如果您是,则无需创建数组 每次加 1 个标量。 我的打印语句显示了从 数据集。使用hf['array'][:] 而不是np.array(hf.get('array'))。 我更喜欢打开文件一次(除非有令人信服的理由来打开和关闭)。这消除了文件设置/拆卸开销。我没有这样做。如果您愿意,请将with / as: 行移动到主行,并将生成的hf 对象传递给create_array()update_array()functions。如果你这样做,你可以很容易地整合这两个功能。 (您将需要逻辑来测试 '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')

【讨论】:

谢谢你的意见。这正是我想在我的方法中模仿的。

以上是关于如何在 python 的帮助下跟踪和显示 HDF5 文件中所做的不断变化的主要内容,如果未能解决你的问题,请参考以下文章

在 Python 中跟踪消息的传递状态

如何在 Python 中查找 HDF5 文件组/键?

表和 HDF5 python 包的问题

如何有效地将数据附加到 C 中的 HDF5 表?

如何使用 Python 和 h5py 读取 HDF5 属性(元数据)

结合 Java、Python、PyTables 和 HDF5 的简单有效的解决方案