跳转到主要内容

HDF5的简易导航和数据存储

项目描述

HDF5的简易导航和数据存储

Python package Coverage Status Binder

层次数据格式(HDF)旨在确保科学和工程数据在各个平台和环境中的高效和公平访问。h5py包提供了一个Python接口来访问HDF5二进制数据格式,而h5io包通过引入用于加载和存储Python对象的read_hdf5()write_hdf5()函数来简化该接口。h5io包还提供了一个list_file_contents()函数来打印HDF5文件的内部结构。

Preview

h5io_browser包通过提供指向HDF5文件层次结构中特定路径的指针h5io_browser.Pointer来扩展此接口。使用此指针,可以从HDF5文件中读取、存储、复制和删除数据,同时简化文件层次结构中的导航。h5io_browser包的开发遵循三个约束和目标。

  • 简化由h5io包创建的HDF5文件的导航。这包括在交互式Python壳或Jupyter Notebook环境中进行交互式导航。
  • 集成标准功能,使用由h5py包和h5io包定义的接口来与HDF5文件中存储的数据进行交互,如读取、写入、复制和删除。
  • 最后,平衡灵活性和性能。与h5io包一样,h5io_browser仅在访问数据时打开HDF5文件,并在等待用户输入时不保持打开的文件句柄。同时,h5io包定义的接口被扩展以同时存储多个Python对象,以改进性能。

安装

可以通过Python包索引(Python Package Index)安装h5io_browser包。

pip install h5io_browser

或者,也可以通过由conda-forge社区维护的社区频道conda包管理器安装。

conda install -c conda-forge h5io_browser

示例

演示h5io_browser模块的基本功能。

导入模块

首先导入h5io_browser模块。

import h5io_browser as hb

从h5io_browser模块创建一个Pointer()对象来访问名为new.h5的新HDF5文件。

hp = hb.Pointer(file_name="new.h5")

写入数据

为了演示,将三个不同的对象写入HDF5文件。

  • 一个包含数字一和二的列表存储在HDF5路径data/a_list中。
  • 一个整数存储在HDF5路径data/an_integer_number中。
  • 一个字典存储在HDF5路径data/sub_path/a_dictionary中。

这可以通过从Python字典访问中已知的边表示法来完成,或者使用write_dict()函数,该函数可以在打开一次文件的同时将多个对象存储在HDF5文件中。

hp["data/a_list"] = [1, 2]
hp.write_dict(data_dict={
    "data/an_integer_number": 3,
    "data/sub_path/a_dictionary": {"d": 4, "e": 5},
})

读取数据

h5io_browser包的一个优点是支持交互式Python环境,如Jupyter笔记本。要浏览HDF5文件,请执行Pointer()对象。

hp

相比之下,字符串表示法列出了file_nameh5_path以及此h5_path处的nodesgroups

str(hp)
>>> 'Pointer(file_name="/Users/jan/test/new.h5", h5_path="/") {"groups": ["data"], "nodes": []}'

使用list_all()函数列出当前h5_path处HDF5文件的目录内容。

hp.list_all()
>>> ['data']

类似地,任何h5_pathgroupsnodes,无论是相对于当前h5_path还是作为绝对h5_path,都可以使用list_h5_path()进行分析。

hp.list_h5_path(h5_path="data")
>>> {'groups': ['sub_path'], 'nodes': ['a_list', 'an_integer_number']}

要继续浏览HDF5文件,可以使用边缘括号表示法,就像通常用于Python字典浏览HDF5文件一样。

hp["data"].list_all()
>>> ['a_list', 'an_integer_number', 'sub_path']

返回的对象仍然是带有更新后的 h5_path 的指针,该路径已从 / 更改为 /data

hp.h5_path, hp["data"].h5_path
>>> ('/', '/data')

最后,可以使用相同的语法和文件系统中已知的 / 表示法或通过组合多个边缘括号来加载HDF5文件的各个节点。

hp["data/a_list"], hp["data"]["a_list"]
>>> ([1, 2], [1, 2])

转换为字典

为了计算地浏览HDF5文件的内容,to_dict() 方法扩展了交互式浏览功能。默认情况下,它返回一个平面字典,键表示各个节点的 h5_path,值是存储在这些节点中的数据。内部,它从当前的 h5_path 开始加载整个树结构,因此根据HDF5文件的大小,这可能需要相当长的时间。

hp.to_dict()
>>> {'data/a_list': [1, 2],
>>>  'data/an_integer_number': 3,
>>>  'data/sub_path/a_dictionary': {'d': 4, 'e': 5}}

另一种表示方法是层次表示法,可以通过将 hierarchical 设置为 True 来启用。然后数据以嵌套字典的形式表示。

hp.to_dict(hierarchical=True)
>>> {'data': {'a_list': [1, 2],
>>>   'an_integer_number': 3,
>>>   'sub_path': {'a_dictionary': {'d': 4, 'e': 5}}}}

With语句

为了与其他文件访问方法兼容,h5io_browser 包也支持with语句表示法。技术上这并不改变行为,即使在with语句中打开,HDF5文件也会在各个函数调用之间关闭。

with hb.Pointer(file_name="new.h5") as hp:
    print(hp["data/a_list"])
>>> [1, 2]

删除数据

要使用 h5io_browser 从HDF5文件中删除数据,可以使用类似于从Python字典中删除条目的标准Python del 函数。为了演示删除操作,添加了一个名为 data/new/entry/test 的新节点。

hp["data/new/entry/test"] = 4

要列出节点,使用 to_dict() 函数并带有 hierarchical 参数来突出显示嵌套结构。

hp["data/new"].to_dict(hierarchical=True)
>>> {'entry': {'test': 4}}

然后使用 del 函数删除节点。虽然这从索引中删除了节点,但文件大小保持不变,这是HDF5格式的一个限制。因此,不建议频繁地在HDF5文件中创建和删除节点。

print(hp.file_size())
del hp["data/new/entry/test"]
print(hp.file_size())
>>> (18484, 18484)

即使删除了最后一个节点,组仍然包含在HDF5文件中。它们不会被 to_dict() 函数列出,因为它递归地遍历当前 h5_path 下的所有节点。

hp["data/new"].to_dict(hierarchical=True)
>>> {}

仍然可以使用 list_all() 函数列出当前 h5_path 的所有节点和组,包括空组,如本例中的 entry 组。

hp["data/new"].list_all()
>>> ['entry']

要从HDF5文件中删除组,使用相同的 del 命令。

del hp["data/new"]

删除了新创建的组和它们的节点后,HDF5文件的原有层次结构得到恢复。

hp.to_dict(hierarchical=True)
>>> {'data': {'a_list': [1, 2],
>>>  'an_integer_number': 3,
>>>  'sub_path': {'a_dictionary': {'d': 4, 'e': 5}}}}

即使在删除了HDF5文件中的节点之后,文件大小仍然保持不变。

hp.file_size()
>>> 18484

遍历节点

为了简化递归遍历所选 h5_path 中包含的所有节点,可以使用 Pointer() 对象作为迭代器。

hp_data = hp["data"]
{h5_path: hp_data[h5_path] for h5_path in hp_data}
>>> {'a_list': [1, 2],
>>>  'an_integer_number': 3,
>>>  'sub_path/a_dictionary': {'d': 4, 'e': 5}}

复制数据

除了向现有HDF5文件添加、浏览和删除数据外,Pointer() 对象还可以用于在给定的HDF5文件内复制数据或从HDF5文件复制数据到另一个文件。创建了一个新的HDF5文件,命名为 copy.h5

hp_copy = hb.Pointer(file_name="copy.h5")

使用 copy_to() 函数将数据从现有的 Pointer() 对象传输到新的HDF5文件。

hp["data"].copy_to(hp_copy)
hp_copy

免责声明

虽然我们努力开发一个稳定可靠的软件库,但开发仍是一个开源项目,根据BSD 3-Clause许可证,没有任何保证。

BSD 3-Clause License

Copyright (c) 2023, Jan Janssen
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

* Neither the name of the copyright holder nor the names of its
  contributors may be used to endorse or promote products derived from
  this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

项目详情


下载文件

下载适用于您平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。

源分发

h5io_browser-0.1.2.tar.gz (23.8 kB 查看哈希值)

上传时间

构建分发

h5io_browser-0.1.2-py3-none-any.whl (23.7 kB 查看哈希值)

上传时间 Python 3

由以下支持