如果添加 h5py 属性的值,为什么 h5 文件的大小没有改变?



例如,我创建了一个带有数据集的h5文件。然后,我向数据集添加了一个属性。为什么不更改文件的大小?创建数据集时是否自动分配属性的存储?

将打印以下代码:2848 2848 0

with h5py.File('dump.h5', 'a') as fid:
fid.create_dataset('data', data=np.zeros([10, 10]))
s1=os.path.getsize('dump.h5')
with h5py.File('dump.h5', 'a') as fid:
fid['data'].attrs.modify('pi', np.string_("3.1415926"))
s2=os.path.getsize('dump.h5')
print(s1, s2, s2-s1)

我的回答扩展了@Homer512的评论。属性最初旨在保存";"小比特";数据(又称元数据(。通常,这些是标量(字符串、int、浮点(,但也可以是较大的对象(例如,np.arrays(。HDF小组认为最大属性大小为64K字节。最初,属性存储在对象的头中(称为"紧凑存储"(。随着时间的推移,HDF集团增加了两种新的存储方式";"大";HDF5库的属性(>64K字节(:1(密集属性存储(在版本1.8中添加(或2(作为单独的数据集(使用对象引用(。此外,随着属性数量的增加,与属性相关的性能也会降低。在这些情况下,可以使用密集属性存储来提高性能。

话虽如此,但大多数时候你不必担心存储机制。

为了演示,我扩展了您的示例,展示了两种不同的行为:1(添加更多属性以增加所需空间,2(创建一个以空10x10数组为属性的组(但没有创建10x10数据集(。运行下面的代码,当你这样做时,你会看到文件大小增加。

h5_file = 'dump.h5'
with h5py.File(h5_file, 'w') as fid:
fid.create_dataset('data', data=np.zeros([10, 10]))
s1=os.path.getsize(h5_file)
with h5py.File(h5_file, 'a') as fid:
fid['data'].attrs.modify('pi', np.string_("3.1415926"))
s2=os.path.getsize(h5_file)
print(f'Sizes for {h5_file}:n{s1}, {s2}, {s2-s1}n')
h5_file = 'dump1.h5'
with h5py.File(h5_file, 'w') as fid:
fid.create_dataset('data', data=np.zeros([10, 10]))
s1=os.path.getsize(h5_file)
attr_dict = {'Version': 3.0, 
'Date created': '2022-03-02',
'Description': 'Example with several attributes',
'Creator': 'kcw78' }
with h5py.File(h5_file, 'a') as fid:
for k,v in attr_dict.items():
fid['data'].attrs[k] = v
s2=os.path.getsize(h5_file)
print(f'Sizes for {h5_file}:n{s1}, {s2}, {s2-s1}n')
h5_file = 'dump2.h5'
with h5py.File(h5_file, 'w') as fid:
fid.create_group('group1')
s1=os.path.getsize(h5_file)
with h5py.File(h5_file, 'a') as fid:
fid['group1'].attrs.modify('arr', np.zeros([10, 10]))
s2=os.path.getsize(h5_file)
print(f'Sizes for {h5_file}:n{s1}, {s2}, {s2-s1}n')

输出为:

Sizes for dump.h5:
2848, 2848, 0
Sizes for dump1.h5:
2848, 8992, 6144
Sizes for dump2.h5:
1832, 2776, 944

如果查看HDF5规范,您会发现属性存储在对象标头中(直到标头空间不足并分配了一个延续块(。所以,大概,您的属性被写入了预先分配的空间中。试着写一个较大的属性或许多较小的属性,直到你越过一个合理的限制,比如64kiB,然后看看它是否会改变。

此外,空间是从磁盘上的堆(确切地说是多个堆(分配的。因此,这也使得文件大小的更改不那么直接。

最新更新