简介
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