h5py学习(二)Datasets
数据集datasets与NumPy数组非常相似。它们是同类数据元素的集合,具有不可变的数据类型和(超)矩形的形状。与NumPy数组不同,它们支持多种透明的存储特征,例如压缩、错误检测和分块I/O。
这些特性在h5py中通过一个thin proxy class 细代理类表示,这个类支持常见的NumPy操作(如切片),以及各种描述性属性:
- shape属性
- size属性
- ndim属性
- dtype属性
- nbytes属性
h5py支持大多数NumPy数据类型,并使用和Numpy相同的字符代码(例如。‘f’
,‘18’
)和dtype machinery。对于h5py支持的数据类型列表,参见FAQ。
创建datasets
新的datasets是使用Groups.create_dataset()
或Group.require_dataset()
创建。现有数据集应使用group indexing语法(dset = group["name"]).
要初始化dataset,只需指定名称、形状和可选的数据类型(默认为'f'
):
>>> dset = f.create_dataset("default", (100,)) >>> dset = f.create_dataset("ints", (100,), dtype='i8')
注意: 这与创建空数据集不同.
您还可以通过提供data参数将dataset初始化为现有的NumPy数组:
>>> arr = np.arange(100) >>> dset = f.create_dataset("init", data=arr)
关键词shape
和dtype
可与data
同时指定; 如果是的这样话,他们会覆盖data.shape
和data.dtype
. 以下是必须的:(1) 在shape
中的总点数要和data.shape
中的总点数匹配,(2)可以将data.type
强制转换为请求的dtype
.
读写数据
HDF5数据集重用NumPy切片语法来读写文件。切片操作直接翻译成HDF5“hyperslab”选择, 它是访问文件中数据的一种快速有效的方法。以下切片参数可以识别:
- Indices:可以转换为Python long的任何内容
- Slices(即
[:]
或[0:10]
)- Field names,对于复合数据
- 最多一个
Ellipsis
(...
)对象- 空元组(
()
)检索所有数据或scalar数据
以下是一些示例(输出省略)。
>>> dset = f.create_dataset("MyDataset", (10,10,10), 'f') >>> dset[0,0,0] >>> dset[0,2:10,1:9:3] >>> dset[:,::2,5] >>> dset[0] >>> dset[1,5] >>> dset[0,...] >>> dset[...,6] >>> dset[()]
关于numpy的哪些部分,有更多的文档fancy indexing提供h5py版本。
对于复合数据,建议将字段名与数字切片分开:
>>> dset.fields("FieldA")[:10] # Read a single field >>> dset[:10]["FieldA"] # Read all fields, select in NumPy
也可以混合索引和字段名(dset[:10,"FieldA"]),但在未来的h5py版本中,这可能会被删除。
检索scalar数据集,您可以使用相同的语法如NumPy: result = dset[()]
. 换句话说,索引到使用空元组的数据集。
对于简单切片,支持广播:
>>> dset[0,:,:] = np.arange(10) # Broadcasts to (10,10)
广播使用重复的Hyperlab选择来实现,并且安全使用非常大的目标选择。仅支持以上功能“简单”的切片(整数、切片和省略号)。
警告: 目前h5py不支持嵌套复合类型,请参阅GH1197号对于更多信息。
多重索引
对数据集进行索引时,会将numpy数组加载到内存中。如果您尝试对它进行两次索引以写入数据,您可能会惊讶于这似乎没起作用:
>>> f = h5py.File('my_hdf5_file.h5', 'w') >>> dset = f.create_dataset("test", (2, 2)) >>> dset[0][1] = 3.0 # No effect! >>> print(dset[0][1]) 0.0
上面的赋值只修改加载的数组。相当于:
>>> new_array = dset[0] >>> new_array[1] = 3.0 >>> print(new_array[1]) 3.0 >>> print(dset[0][1]) 0.0
要在单个步骤中合并数据集,请执行以下操作:
>>> dset[0, 1] = 3.0 >>> print(dset[0, 1]) 3.0
长度和迭代
与NumPy数组一样,一个dataset的len()
是第一个轴上的长度,所以对数据集的迭代将在第一个轴上迭代。然而,对生成数据的修改不会记录在文件中。在迭代时调整一个dataset的大小将会有undefined的结果。
在32位平台上,如果第一个轴的长度大于2**32,len(dataset)
将会失败。对于大型数据集建议使用Dataset.len()
。
分块存储
使用默认设置创建的HDF5数据集将是contiguous相邻的; 换句话说,在磁盘上将按传统的C顺序排列。数据集也可能使用HDF5创建chunked块存储布局。这意味着dataset是分成有规则大小的块,随意地存储在磁盘上,并使用B-树建立索引。
分块存储可以调整数据集的大小,因为存储在固定大小的块中,以使用压缩过滤器。
要启用分块存储,请设置元组表示块形状:
>>> dset = f.create_dataset("chunked", (1000, 1000), chunks=(100, 100))
数据将被读写成形状为(100,100)的块;例如,dset[0:100,0:100]
中的数据将会存储在文件中,和在范围内dset[400:500,100:200]中的数据点一样
.
分块对性能有影响。建议总数块的大小介于10KiB和1MiB之间,对于较大的数据集,则更大。还要记住,当访问块中的任何元素时,将会从从磁盘读取整个块。
因为选择一个块形状可能会令人困惑,所以可以让h5py猜测一个块适合您的形状:
>>> dset = f.create_dataset("autochunk", (1000, 1000), chunks=True)
如果一个chunk形状没有手动指定的话,如果使用压缩或maxshape,等,自动分块将被启动。
iter_chunks方法返回可用于逐块执行块的迭代器读或写:
>>> for s in dset.iter_chunks(): >>> arr = dset[s] # get numpy array for chunk
可调整大小的datasets
在HDF5中,一旦数据集创建到最大大小,就可以通过调用Dataset.resize()调整大小
. 创建时,通过关键字maxshape()
指定此数据集的最大大小:
>>> dset = f.create_dataset("resizable", (10,10), maxshape=(500, 20))
任何(或所有)轴也可以标记为“unlimited”,在这种情况下,它们可以每轴最多增加2**64个元素的HDF5。使用None来指定
这些轴:
>>> dset = f.create_dataset("unlimited", (10, 10), maxshape=(None, 10))
注意 使用现有数据调整数组的大小与NumPy不同;如果任何轴shrinks缩短,丢失区域的数据都将被丢弃。数据不会“重新排列”自己,这和NumPy数组在resizing时不同。
过滤管道
分块数据可以由HDF5 filter pipeline转换。最常用的用途是透明压缩。数据在写进磁盘时候被压缩,在读取时自动解压。一旦datasets是在应用特定压缩过滤器的情况下创建的,可以和正常一样读取写数据,不需要特殊步骤。
启用compression
关键字Group.create_dataset()
:
>>> dset = f.create_dataset("zipped", (100, 100), compression="gzip")
可以用compression_opts
指定每个过滤器的选项:
>>> dset = f.create_dataset("zipped_max", (100, 100), compression="gzip", compression_opts=9)
无损压缩过滤器
- GZIP过滤器(
“gzip”
) - 每一个安装了HDF5的都可以使用,所以它是便携性最好的。压缩性好,速度适中。通过
compression_opts来
设置压缩级别,可以是0到9之间的整数,默认值为4。 - LZF过滤器(
“lzf”
) - 每次安装h5py时都可以使用(也可以使用C源代码)。低至中等压缩,非常快。没有选择。
- SZIP过滤器(
“szip”
) - NASA社区使用的专利保护的过滤器。因法律原因,不适用于所有安装HDF5。有关过滤器选项,请参阅HDF5文档选项。
自定义压缩过滤器
除了上面列出的压缩过滤器,压缩过滤器可以由底层HDF5库动态加载。通过传递过滤器编号至创建数据集()
作为压缩
参数。这个压缩选项
参数将被传递给这个过滤器。
另请参见
- hdf5plugin
- 一个Python包,包含几个流行的过滤器,包括Blosc、LZ4和ZFP,便于与h5py配合使用
- HDF5 Filter Plugins
- 从HDF Group下载一个过滤器的集合
- Registered filter plugins
- 公开发布的过滤器插件的索引
注意
压缩过滤器的底层实现将具有H5Z_FLAG_OPTIONAL
标志设置。这表明,如果在数据写入时候没有对块进行压缩,将不会抛出错误。这个过滤器随后在读取块时将跳过。
Scale-Offset过滤器
使用启用的过滤器compression
关键词是lossless; HDF5还包括有损过滤器,通过损失精度已换取存储空间。
仅适用于整数和浮点数据。通过设置Group.create_dataset()
关键字scaleoffset
到一个整数,用以启用刻度偏移。
对于整数数据,它指定要保留的位数。设置为0,HDF5将自动计算区块无损压缩所需的位数。对于浮点数据,指示小数点后面要保留的位数。
警告
当前,scale-offset过滤器不保留特殊的浮点值(即NaN、inf),见https://forum.hdfgroup.org/t/scale-offset-filter-and-special-float-values-nan-infinity/3379更多信息和跟进。
Shuffle过滤器
面向块的压缩器(如GZIP或LZF)当在使用类似值的运行时效果更好。启用shuffle过滤器将重新排列可以提高压缩比。没有明显的速度损失,无损。
通过设置Group.create_dataset()
关键字shuffle
为True以开启。
Fletcher32过滤器
向每个块添加校验和以检测数据损坏。尝试阅读损坏的块将失败并出现错误。没有明显的速度惩罚。显然,这不能和有损压缩过滤器一起使用。
通过设置Group.create_dataset()
关键字fletcher32
为True以开启。
多块选择
完整的H5Sselect_hyperslab API通过MultiBlockSlice对象公开。与内置的slice对象需要三个元素来定义不同,它需要四个元素来定义选择(start, count, stride和block)。可以使用MultiBlockSlice 代替切片来选择由跨步分隔的多个元素的多个(计数)块,而不是由步长分隔的一组单个元素。
有关此切片如何工作的说明,请参见HDF5文档.
例如:
>>> dset[...] array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) >>> dset[MultiBlockSlice(start=1, count=3, stride=4, block=2)] array([ 1, 2, 5, 6, 9, 10])
它们可以与任何切片对象一起用于多维切片,包括其他MultiBlockSlices。更完整的例子是,请参见multiblockslice_interleave.py示例脚本。
Fancy indexing索引
支持NumPy花式索引语法的一个子集。把这个和注意,因为底层的HDF5机制可能具有不同的性能比你想象的要多。
对于任何轴,您可以提供一个明确的点列表;为了具有形状(10,10)的数据集:
>>> dset.shape (10, 10) >>> result = dset[0, [1,3,8]] >>> result.shape (3,) >>> result = dset[1:6, [5,8,9]] >>> result.shape (5, 3)
存在以下限制:
- 选择坐标必须按递增顺序给出
- 忽略重复选择
- 元素(>1000)可能产生很长的列表
NumPy布尔“mask”数组也可以用于指定选择。这个此操作的结果是元素排列在标准纽比(C型)订单。在幕后,这会产生一个洗衣店要选择的点列表,因此在使用大遮罩时要小心:
>>> arr = numpy.arange(100).reshape((10,10)) >>> dset = f.create_dataset("MyDataset", data=arr) >>> result = dset[arr > 50] >>> result.shape (49,)
在版本2.10中更改:现在允许使用空列表进行选择。这将返回相关维度中长度为0的数组。
创建和读取空(或空)数据集和属性
HDF5有空或空数据集和属性的概念。这些不是与形状为()的数组或HDF5术语中的标量数据空间相同。相反,它是一个具有关联类型、无数据和形状的数据集。在h5py,我们将其表示为具有形状的数据集没有
,或实例h5py.空
. 无法切片空数据集和属性。
要创建空属性,请使用h5py.空
根据属性:
>>> obj.attrs["EmptyAttr"] = h5py.Empty("f")
类似地,读取空属性将返回h5py.空
:
>>> obj.attrs["EmptyAttr"] h5py.Empty(dtype="f")
可以通过定义数据类型
但是没有形状
在里面创建\u数据集
:
>>> grp.create_dataset("EmptyDataset", dtype="f")
或者数据
的一个实例h5py.空
:
>>> grp.create_dataset("EmptyDataset", data=h5py.Empty("f"))
空数据集的形状定义为没有
,这是确定数据集是否为空。可以“读取”空数据集类似于标量数据集的方法,即如果空的\u数据集
是空的数据集:
>>> empty_dataset[()] h5py.Empty(dtype="f")
数据集的数据类型可以通过<dset>.d类型
正常情况下。由于不能对空数据集进行切片,一些数据集方法,如直接读取
将引发类型错误
如果用于空数据集,则出现异常。
参考文献
- 班
h5py。
数据集
(标识符) -
数据集对象通常通过
创建数据集()
,或者从文件中检索现有的数据集。调用此构造函数创建绑定到现有数据集ID
标识符。__获取项目__
(阿格斯)-
NumPy样式切片以检索数据。看到了吗读写数据.
__集合项目__
(阿格斯)-
NumPy样式的切片以写入数据。看到了吗读写数据.
__布尔__
()-
检查数据集是否可访问。由于多种原因,数据集可能无法访问。例如该文件可能已关闭,也可能属于其他位置。
>>> f = h5py.open(filename) >>> dset = f["MyDS"] >>> f.close() >>> if dset: ... print("datset accessible") ... else: ... print("dataset inaccessible") dataset inaccessible
直接读取
(阵列,source_sel=无,目标选择=无)-
从HDF5数据集直接读取到NumPy数组中,这可以避免像切片一样制作中间副本。这个目标数组必须是C-连续且可写的,并且必须具有可以将源数据强制转换为的数据类型。数据类型转换将由HDF5进行飞行。
源洕sel和目的地选择指示分别是数据集和目标数组。使用的输出
numpy.s
:>>>数据集 = f.创建\u数据集(“数据集”, (100,), 数据类型=“int64”) >>>阿瑞 = np公司.零((100,), 数据类型=“int32”) >>>数据集.直接读取(阿瑞, np公司.s_[0:10], np公司.s_[50:60])
直接写入
(来源,source_sel=无,目标选择=无)-
从NumPy数组直接将数据写入HDF5。源数组必须是C-连续的。选择必须是numpy.s\u[<args>]的输出。广播支持简单索引。
A型
(数据类型)-
返回一个包装器,允许您将数据作为类型。转换由HDF5直接处理,动态:
>>>数据集 = f.创建\u数据集(“大金特”, (1000,), 数据类型=“int64”) >>>外面的 = 数据集.A型('国际16')[:] >>>外面的.数据类型 数据类型('int16')
在版本3.0中更改:允许读取包装器对象。在早期版本中,
类型()
必须用作上下文管理器:>>>具有 数据集.A型('国际16'): ... 外面的 = 数据集[:]
助理
(编码=无,errors='strict')-
仅适用于字符串数据集。返回将数据作为Python读取的包装器字符串对象:
>>>s = 数据集.助理()[0]
编码和错误的工作原理如下
字节。解码()
,但默认编码由数据类型ASCII或UTF-8定义。这不能保证是正确的。3.0版中的新增功能。
领域
(姓名)-
获取包装器以从复合数据类型读取字段子集:
>>>2德鲁坐标 = 数据集.领域([“x”, “是的”])[:]
如果名称是一个字符串,则提取单个字段,并且数组将具有该数据类型。否则,它应该是iterable,读取的数据将有一个复合数据类型。
3.0版中的新增功能。
iter\U块
()-
迭代分块数据集中的块。可选的
选择
论点定义要使用的区域的切片或切片元组。如果未设置,则整个数据空间将用于迭代器。对于给定区域内的每个块,迭代器生成一个给出给定块与选择区域。这可以用来读取或写入数据块.
如果数据集未分块,将引发TypeError。
如果选择区域无效,将引发ValueError。
3.0版中的新增功能。
调整大小
(大小,轴=无)-
更改数据集的形状。大小给元组一个新的数据集形状,或给定指定的新长度的整数轴.
数据集的大小只能调整到
Dataset.maxshape
.
伦恩
()-
返回第一个轴的大小。
制造规模
(名称='')-
将此数据集设为HDF5尺寸比例尺.
然后可以将其附加到其他数据集的维度,如下所示:
其他.暗淡[0].附加比例尺(ds公司)
您可以选择传递与此比例关联的名称。
形状
-
提供数据集维度的NumPy样式形状元组。
数据类型
-
提供数据集类型的NumPy dtype对象。
大小
-
提供数据集中元素总数的整数。
字节
-
整数,给出将整个数据集加载到RAM中所需的总字节数(即。数据集[()]).这可能不是数据集占用的磁盘空间量,因为数据集可能在写入时被压缩,或者只被数据部分填充。这个值也不包括数组开销,因为它只描述数据本身的大小。因此,这个数据集占用的RAM的实际量可能稍大一些。
3.0版中的新增功能。
新吉布提国际机场
-
提供数据集中维度总数的整数。
最大形状
-
NumPy样式的形状元组,指示最大尺寸可以调整数据集的大小。轴
没有
是无限的。
大块
-
提供块形状的元组,如果未使用分块存储,则无。看到了吗分块存储.
压缩
-
使用当前应用的压缩筛选器的字符串,如果没有为此数据集启用压缩。看到了吗过滤管道.
压缩选项
-
压缩过滤器的选项。看到了吗过滤管道.
刻度偏移
-
设置HDF5刻度偏移过滤器(整数),如果此数据集不使用缩放偏移压缩。看到了吗刻度偏移滤波器.
洗牌
-
是否应用洗牌过滤器(T/F)。看到了吗洗牌过滤器.
弗莱彻32
-
是否启用Fletcher32校验和(T/F)。看到了吗弗莱彻32过滤器.
填充值
-
读取数据集的未初始化部分时使用的值,或“无”如果没有定义填充值,在这种情况下,HDF5将使用键入适当的默认值。无法在数据集之后更改创建。
外部的
-
如果此数据集存储在一个或多个外部文件中,则这是一个列表三元组,比如
外部=
参数到创建数据集()
. 否则,它就是没有
.
你是虚拟的吗
-
如果此数据集是虚拟数据集,否则为False。
暗淡
-
访问比例尺尺寸.
属性
-
属性对于此数据集。
身份证件
-
数据集的低级标识符;一个实例
数据集ID
.
裁判
-
指向此数据集的HDF5对象引用。看到了吗使用对象引用.
区域参考
-
用于创建HDF5区域引用的代理对象。看到了吗使用区域参照.
名称
-
提供此数据集的完整路径的字符串。
文件
-
文件
此数据集所在的实例
起源
-
集团
包含此数据集的实例。
过滤器
posted @ 2021-11-08 22:05