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

时间:2016-05-20 16:13:28

标签: python h5py

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

似乎属性使用某种比例/维度,因为你无法修改数据的形状?!我甚至没有更改阵列形状,只有少数几个元素。我认为属性是任意的,只要您不尝试更改数据类型(或数组形状),您就可以根据需要进行修改。或者这是一些Python / C端口错误?

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

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

1 个答案:

答案 0 :(得分:1)

检查HDF5文件时:

enter image description here

你看到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)将其写回来,您就会得到“数据形状与现有属性不兼容”的错误。

您可以读取属性,修改它并将其分配回来:

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

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

enter image description here

所以我试图欺骗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数组,如果它们是嵌套数组,则不允许修改属性而不更改形状。这可能被视为一个错误。您可以做的最好的事情是避免嵌套数组支持更高维数组作为属性形状,因为它们可以修改而不会抛出错误。