如果是嵌套数组,则无法修改数据集属性

Unable to modify dataset attribute if it is a nested array

this HDF5中,我需要更新第一行属性

h5['Model/dataset'].attrs['num_cells']

所以,我执行以下操作:

import h5py

h5 = h5py.File('MCPL507_HS_3_2_orig.newrom','a')
numcells = h5['Model/dataset'].attrs['num_cells'][:]

#Print before re-assigment
print numcells[0]
print type(numcells[0])

numcells[0] = [230,230,30]

#Print after re-assigment
print numcells[0]
print type(numcells[0])

h5['Model/dataset'].attrs.modify('num_cells',numcells)

这会引发异常:

File "C:\Users\nnolde\PycharmProjects\HDF5_Stuff\MinExample.py", line 16, in <module>
    h5['Model/dataset'].attrs.modify('num_cells',numcells)
  File "C:\Anaconda2\lib\site-packages\h5py\_hl\attrs.py", line 221, in modify
    raise TypeError("Shape of data is incompatible with existing attribute")
TypeError: Shape of data is incompatible with existing attribute

似乎该属性使用了某种 scale/dimension,因为您不能修改数据的形状?!我什至没有改变数组的形状,只改变了几个元素。我认为属性是任意的,只要您不尝试更改数据类型(或数组形状),就可以根据需要进行修改。或者这是一些 Python/C 端口错误?

注意:我无法使用 __setitem__,这将导致我们的自定义应用程序无法再识别 HDF5。

有没有人知道可能是什么问题,甚至可能如何解决它?

检查 HDF5 文件时:

你看到 num_cells 是一个数组(大小 3)的嵌套数组(大小 3)。

然而,在 Python 阅读之后。

h5 = h5py.File('MCPL507_HS_3_2_orig.newrom','a')
numcells = h5['Model/dataset'].attrs['num_cells']
print(numcells.shape)

numcells的形状是(3,3),也就是说h5py在读取属性的时候把嵌套的线性数组变成了二维数组

即使不修改,只需使用 modify(name, value) 将其写回,您也会收到 "Shape of data is incompatible with existing attribute" 错误。

您可以像这样读取属性、修改它并重新分配它:

numcells = h5['Model/dataset'].attrs['num_cells']
numcells[0] = [230,230,30]
h5['Model/dataset'].attrs['num_cells'] = numcells

但这会将 HDF5 文件中的属性形状更改为 3x3(无论如何你说你不能使用它):

所以我尝试欺骗h5py并将属性拆分为三个一维数组以手动创建那里的内容,然后再次设置它:

numcells = h5['Model/dataset'].attrs['num_cells']
numcells[0] = [230,230,30]
dummy = [numcells[0], numcells[1], numcells[2]]
h5['Model/dataset'].attrs['num_cells'] = dummy

但 h5py 知道得更多,并再次将它们转换为 3x3 数组!

总结:

h5py 在读写属性时将嵌套数组转换为更高维的 numpy 数组,如果它们是嵌套数组,则不允许在不改变形状的情况下修改属性。这可以看作是一个错误。您能做的最好的事情就是避免嵌套数组,而使用高维数组作为属性形状,因为它们可以在不引发错误的情况下进行修改。