[1233]Python数据存储之h5py详解

2023-10-17 19:11:31 浏览数 (2)

简介

h5py官方文档:https://docs.h5py.org/en/stable/build.html

h5py是Python中用于读取和写入HDF5文件格式数据的软件包,HDF指的是层次型数据格式(HDF: Hierarchical Data Format),主要用于存储和管理大数据集和复杂数据对象的工具。

h5py能够读写HDF5文件,并具有简单、自然和Pythonic的API。它支持Numpy数组、Python字符串等,并且能够保存Python对象的一些特定信息(如用户定义的元数据)。因此,h5py也经常被用作一个通用的数据存储文件格式。

核心概念:

一个HDF5文件是一种存放两类对象的容器:dataset和group。 Dataset是类似于数组的数据集,而group是类似文件夹一样的容器,存放dataset和其他group。在使用h5py的时候需要牢记一句话:groups类比词典,dataset类比Numpy中的数组。

HDF5的dataset虽然与Numpy的数组在接口上很相近,但是支持更多对外透明的存储特征,如数据压缩,误差检测,分块传输。

安装

为了安装h5py,可以使用pip进行安装:

代码语言:javascript复制
pip install h5py

安装完成后,可以开始使用h5py库。

使用h5py

创造一个HDF5文件

可以使用以下代码在Python中创建一个HDF5文件:

代码语言:javascript复制
import h5py

# 创建HDF5文件
with h5py.File('data.h5', 'w') as f:
    # 创建一个dataset
    dset = f.create_dataset('mydataset', (100,), dtype='i')
    # 填充dataset
    dset[...] = range(100)

以上代码创建了一个名为“data.h5”的HDF5文件,并在其中创建了一个名为“mydataset”的dataset,它包含100个整数。

注:with语句会在代码块执行完毕后自动完成文件的关闭操作,保证了程序的健壮性。

读取一个HDF5文件
代码语言:javascript复制
import h5py

# 读取HDF5文件
with h5py.File('data.h5', 'r') as f:
    # 读取名为“mydataset”的dataset
    dset = f['mydataset']
    # 打印dataset的所有属性
    print(dset.attrs.keys())
    # 打印dataset的形状和数据类型
    print(dset.shape, dset.dtype)
    # 打印dataset的所有值
    print(dset[...])

以上代码读取了名为“data.h5”的HDF5文件,并读取了其中名为“mydataset”的dataset,然后打印了dataset的属性、形状、数据类型和所有值。

查看h5文件还可以使用以下方法,通过一个软件查看这个文件里的内容

1.从pycharm中进入自己的环境

2.pip install vitables

3.执行 vitables 文件名.hdf5

示例1:利用h5py储存Numpy数组
代码语言:javascript复制
import h5py
import numpy as np

# 创建numpy数组
data = np.random.randint(0, 100, size=(100, 100))

# 存储numpy数组
with h5py.File('data.h5', 'w') as f:
    dset = f.create_dataset('mydataset', data=data)

以上代码创建了一个100x100的Numpy数组,然后使用h5py将Numpy数组写入到名为“data.h5”的HDF5文件中。

示例2:存储List和Dict
代码语言:javascript复制
import h5py

# 定义一个List和Dict
mylist = [1, 2, 3, 4, 5]
mydict = {'a': 1, 'b': 2, 'c': 3}

# 存储List和Dict
with h5py.File('data.h5', 'w') as f:
    f.create_dataset('mylist', data=mylist)
    for key, value in mydict.items():
        f.attrs[key] = value

以上代码定义了一个List和一个Dict,然后使用h5py将它们写入到名为“data.h5”的HDF5文件中。其中,List被存储为名为“mylist”的dataset,而Dict则使用文件的属性(attributes)存储。

分块存储策略
代码语言:javascript复制
>>> import h5py
>>> import numpy as np
>>> f = h5py.File("mytestfile.hdf5", "w")

# 其中create_dataset用于创建给定形状和数据类型的空dataset
>>> arr = np.arange(100)
>>> dset = f.create_dataset("init", data=arr)

在缺省设置下,HDF5数据集在内存中是连续布局的,也就是按照传统的C序。Dataset也可以在HDF5的分块存储布局下创建。也就是dataset被分为大小相同的若干块随意地分布在磁盘上,并使用B树建立索引。

为了进行分块存储,将关键字设为一个元组来指示块的形状。

代码语言:javascript复制
>>> dset = f.create_dataset("chunked", (1000, 1000), chunks=(100, 100))

# 也可以自动分块,不必指定块的形状。
>>> dset = f.create_dataset("autochunk", (1000, 1000), chunks=True)

HDF5的分层结构

“HDF”代表”Hierarchical Data Format”(分层数据格式)。 HDF5文件中group对象类似于文件夹,我们创建的文件对象本身就是一个group,称为root group。

代码语言:javascript复制
>>> f.name
u'/'

创建subgroup是使用create_group的方法实现的。但是我们需要先用读写模式打开文件:

代码语言:javascript复制
>>> f = h5py.File('mydataset.hdf5', 'r ')
>>> grp = f.create_group("subgroup")

然后grp就具有和f一样的方法了。

我们在group上迭代从而得到group内所有的直接附属的成员(包括dataset和subgroup)

代码语言:javascript复制
>>> for name in f:
...     print name
mydataset
subgroup
subgroup2

为了遍历一个group内的所有直接和间接成员,我们可以使用group的visit()和visititerms()方法,这些方法需要接收一个回调函数作为参数。

代码语言:javascript复制
>>> def printname(name):
...     print name
>>> f.visit(printname)
mydataset
subgroup
subgroup/another_dataset
subgroup2
subgroup2/dataset_three

属性

HDF5的一个很棒的特点是你可以在数据旁边存储元数据。所有的group和dataset都支持叫做属性的数据形式。属性通过attrs成员访问,类似于 python中词典格式。

代码语言:javascript复制
>>> dset.attrs['temperature'] = 99.5
>>> dset.attrs['temperature']
99.5
>>> 'temperature' in dset.attrs
True

高级特征

1) 滤波器组

HDF5的滤波器组能够对分块数组进行变换。最常用的变换是高保真压缩。使用一个特定的压缩滤波器创建dataset之后,读写都可以向平常一样,不必添加额外的步骤。  用关键词compression来指定压缩滤波器,而滤波器的可选参数使用关键词compression_opt来指定:

代码语言:javascript复制
>>> dset = f.create_dataset("zipped", (100, 100), compression="gzip")

2) HDF5文件的限制 a. HDF5文件本身大小没有限制,但是HDF5的一个dataset最高允许32个维,每个维度最多可有2^64个值,每个值大小理论上可以任意大

b. 目前一个chunk允许的最大容量为2^32-1 byte (4GB). 大小固定的dataset的块的大小不能超过dataset的大小。

参考:https://pythonjishu.com/fdpcncujhigbmkh/ https://blog.51cto.com/u_19261/6999011 https://zhuanlan.zhihu.com/p/549538285

0 人点赞