h5py:分配或广播到结构化数组中的 2×2 列

h5py: assigning or broadcasting to 2×2 column in a structured array

我有一个包含 2×2 固定大小项目的记录数组,有 10 行;因此该列是 10×2x2。我想为整列分配一个常量。 Numpy 数组将正确广播标量值,但这在 h5py 中不起作用。

import numpy as np
import h5py
dt=np.dtype([('a',('f4',(2,2)))])
# h5py array
h5a=h5py.File('/tmp/t1.h5','w')['/'].require_dataset('test',dtype=dt,shape=(10,))
# numpy for comparison
npa=np.zeros((10,),dtype=dt)


h5a['a']=np.nan 
# ValueError: changing the dtype of a 0d array is only supported if the itemsize is unchanged

npa['a']=np.nan 
# numpy: broadcasts, OK

事实上,我找不到不广播的分配列的方法:

h5a['a']=np.full((10,2,2),np.nan)
# 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

连一个元素行都没有:

h5a['a',0]=np.full((2,2),np.nan)
# 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

这里有什么问题?

In [69]: d = f.create_dataset('test', dtype=dt, shape=(3,))

我们可以设置一个类似大小的数组:

In [90]: x=np.ones(3,dt)
In [91]: x[:]=2
In [92]: x
Out[92]: 
array([([[2., 2.], [2., 2.]],), ([[2., 2.], [2., 2.]],),
       ([[2., 2.], [2., 2.]],)], dtype=[('a', '<f4', (2, 2))])

并将其分配给数据集:

In [93]: d[:]=x
In [94]: d
Out[94]: <HDF5 dataset "test": shape (3,), type "|V16">
In [95]: d[:]
Out[95]: 
array([([[2., 2.], [2., 2.]],), ([[2., 2.], [2., 2.]],),
       ([[2., 2.], [2., 2.]],)], dtype=[('a', '<f4', (2, 2))])

我们也可以用正确的数据类型创建一个单元素数组,然后赋值:

In [116]: x=np.array((np.arange(4).reshape(2,2),),dt)
In [117]: x
Out[117]: array(([[0., 1.], [2., 3.]],), dtype=[('a', '<f4', (2, 2))])
In [118]: d[0]=x

使用h5py我们可以用记录和字段作为索引:

In [119]: d[0,'a']
Out[119]: 
array([[0., 1.],
       [2., 3.]], dtype=float32)

其中 ndarray 需要双索引,例如:d[0]['a']

h5py 试图模仿 ndarray 索引,但并不完全相同。我们只能接受这一点。

编辑

[118]赋值也可以

In [207]: d[1,'a']=x

这里的dt只是作为一个字段,但我认为这应该适用于多个字段。关键是该值必须是与 d 字段规范匹配的结构化数组。

我刚刚在文档中注意到他们正试图摆脱 d[1,'a'] 索引,而是使用 d[1]['a']。但是对于似乎不起作用的分配 - 不是错误,只是没有采取行动。我认为 d[1]d['a'] 是一个副本,相当于数组的高级索引。对于结构化数组,它们是 view.