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)

关键词shapedtype可与data同时指定; 如果是的这样话,他们会覆盖data.shapedata.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公司)

您可以选择传递与此比例关联的名称。

虚拟源()

如果此数据集是虚拟数据集,返回列表命名元组:(vspace, 文件名, 数据集名称, src_空格),描述数据集的哪些部分映射到哪些源数据集。这两个“空间”成员是低级成员空间ID物体。

形状

提供数据集维度的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

posted @ 2024-09-04 05:39  chinagod  阅读(55)  评论(0编辑  收藏  举报