【发布时间】:2020-09-28 17:37:16
【问题描述】:
我知道在c 中,我们可以使用struct 类型轻松构建复合数据集,并逐块分配数据。我目前正在Python 和h5py 中实现类似的结构。
import h5py
import numpy as np
# we create a h5 file
f = h5py.File("test.h5") # default is mode "a"
# We define a compound datatype using np.dtype
dt_type = np.dtype({"names":["image","feature"],
"formats":[('<f4',(4,4)),('<f4',(10,))]})
# we define our dataset with 5 instances
a = f.create_dataset("test", shape=(5,), dtype=dt_type)
要写入数据,我们可以这样做...
# "feature" array is 1D
a['feature']
输出是
array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]], dtype=float32)
# Write 1s to data field "feature"
a["feature"] = np.ones((5,10))
array([[1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]], dtype=float32)
问题是当我将二维数组“图像”写入文件时。
a["image"] = np.ones((5,4,4))
ValueError: When changing to a larger dtype, its size must be a divisor of the total size in bytes of the last axis of the array.
我阅读了文档并进行了研究。不幸的是,我没有找到好的解决方案。我知道我们使用group/dataset 来模拟这种复合数据,但我真的想保留这种结构。有什么好办法吗?
任何帮助将不胜感激。谢谢。
【问题讨论】:
-
当我创建一个具有该形状和 dtype 的数组时,您的
ones分配有效。a['image'] = np.ones((5,4,4), 'f4')有效吗?np.ones可能默认为float64,而h5py无法将其转换为float32。也许以后我会用h5py试试。 -
@hpaulj 感谢您的回复。这没用。
dtype遵循我们在开头定义的内容。在我们的例子中,它是float32,分配的值的类型将被强制为 float32。 -
我可以用那个 dtype 和 shape 创建一个 numpy 数组,用
np.ones设置它的“image”字段。a[:] = arr有效。a['image'][:] = np.ones((5,4,4))也有效。 -
我的理解是
h5py使用cython代码与HDF5C++API接口。由于 numpy 数组可以设置字段值,我怀疑我们在这里看到的限制来自 HDF5 本身,而不是来自h5py开发人员的一些懒惰。 -
看一些其他的例子,我们可能需要多注意错误信息和位置。
__setitem__代码是 Python。问题可能仅限于二维字段。此外,numpy在处理多字段索引的方式上做了一些更改。