返回介绍

3.3 改变数据集的形状

发布于 2024-01-25 22:02:55 字数 3633 浏览 0 评论 0 收藏 0

目前为止,我们已经了解数据集有形状和类型。类型是固定的,不可更改。但是形状可以在一定范围内被改变。

让我们创建一个具有4个元素的数据集看看:

查看一下dset的特征,我们会看到除了.shape特征以外,还有一个叫maxshape的特征:

Dataset对象还有一个叫resize的方法。让我们看看当我们试图将数据集从(2, 2)缩小为(1, 1)时会发生什么:

很明显我们漏掉了某些东西。究竟如何才能改变一个数据集的形状呢?

3.3.1 创建可变形数据集

在你创建数据集时,除了设置其形状,你还可以通过h5py设置是否允许它改变形状,称为maxshape。

和shape一样,maxshape在创建数据集时指定,且无法更改。如前所见,如果你不指定一个maxshape,HDF5会创建一个不可变形的数据集,并设置maxshape = shape。数据集还可以被创建为使用连续存储,这也将导致resize不可用。第四章会对连续存储和分块存储做更详细的说明。我们现在先忽视其细节。

让我们再试一次,这次我们为数据集指定一个maxshape:

成功!改回来行不行呢?

maxshape这个名字告诉你,你不能将一个数据集的shape变的大于maxshape。但如果你在创建数据集的时候还不知道最后形状会变得多大怎么办?是不是应该提供一个超大的数值给maxshape来跨过这个障碍呢?

谢天谢地没这个必要。HDF5有一个“无限”维度的概念来处理这种情况。如果一个维度被声明为“无限”,你可以使其变得任意大。你只需要在maxshape参数上指定该维度为None:

你可以将任意维度声明为无限。

最后,无论maxshape参数为何,你都不能改变维度的个数。这被称为数据集的阶数(rank),阶数是固定的,永远不能改变:

3.3.2 用resize重新组织数据

在你改变数据集形状时NumPy会遵循一组规则。以下面这个形状为(2, 2)的4元素方形数组为例:

现在我们将其resize为(1, 4),保持元素总个数不变,那么所有的值都在,但是会被重新组织:

最后我们将其resize为(1, 10),增加新的元素,那么增加的新元素会被初始化为0。

如果你以前曾经改变过NumPy数组的形状,你应该已经习惯了这种重新组织的行为。HDF5则不同,不会进行重新组织。让我们创建一个具有两个无限维度的Dataset对象进行实验:

现在我们尝试如上例NumPy那样对其进行resize:

发生了什么?当我们将形状从(2, 2)改变为(1, 4)时,位于dset[1,0]和dset[1,1]的数据没有被重新组织,它们被丢掉了。所以在使用resize时你必须非常当心。你在NumPy世界里习以为常的重新组织的把戏很快会产生问题。

最后,你会注意到上例中的新元素都被初始化为0。它们通常都会被设置为数据集的fill value(见25页,默认填充值)。

3.3.3 何时以及如何进行resize

HDF5最常见的问题之一是如何给数据集添加数据。resize可以做到这一点,但是要注意性能。

假设我们已经有一个数据集记录了很多条时序,每条时序有1 000个元素。不过我们的应用程序不知道一共需要存储多少条时序,可能是10、100或1 000条。一种方案如下:

每当我们新增一条1 000元素的时序,数据集都会扩展一条记录。但是如果调用resize的次数等于插入的次数,性能不会很好,特别是当需要新增成千上万条记录时。

另一种方案是记住插入的次数并在结束时“削减”数据集:

在真实世界里,为了获得最佳性能,还有更多的工作要做。如果不讨论HDF5是如何存储数据的,我们就只能讲到这里。所以接下来我们就进入第4章去讨论存储,或者更精确地说,分块存储。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文