如何解决访问.h5文件(Python)上预写数据时的精度错误



我正试图访问以批为单位上传的公共数据集中的数据。每个批都是一个很大的.h5文件,其中包含多个图像。这些图像的属性告诉我用于创建这些图像模拟的设置。以下是我正在运行的访问特定组属性的代码,但偶尔我会遇到一个精度错误,我不知道如何解决。我曾尝试使用astype(np.int64)更改数据类型,但首先访问该属性数据时出现问题。这些属性是数据集所有者当时以高精度保存的数值(小数点后8位(。

这是我用来获取特定组并单独访问属性的代码:

keys = list(f.keys())
key = keys[0]
group = f[key]
print(key)
print(group.attrs.keys())
print(group.attrs['space_group'])
print(group.attrs['formula'])
print(group.attrs['z_dirs'])
print(group.attrs['y_dirs'])
print(group.attrs['semi_angles_rad'])

这是我收到的错误信息:

sample_10_0
<KeysViewHDF5 ['abc_angstrom', 'angles_degree', 'd_hkls_angstrom', 'energy_keV', 'formula', 'material', 'semi_angles_rad', 'space_group', 'y_dirs', 'z_dirs']>
b'9'
Li6 Cu6 P6 O24
[[[ 0  1  2]
[ 0  1 -1]
[ 2 -2  0]]]
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
~AppDataLocalTemp/ipykernel_9836/1283281529.py in <module>
7 print(group.attrs['formula'])
8 print(group.attrs['z_dirs'])
----> 9 print(group.attrs['y_dirs'])
10 print(group.attrs['semi_angles_rad'])
h5py_objects.pyx in h5py._objects.with_phil.wrapper()
h5py_objects.pyx in h5py._objects.with_phil.wrapper()
D:anaconda3envstflibsite-packagesh5py_hlattrs.py in __getitem__(self, name)
59             return Empty(attr.dtype)
60 
---> 61         dtype = attr.dtype
62         shape = attr.shape
63 
h5pyh5a.pyx in h5py.h5a.AttrID.dtype.__get__()
h5pyh5a.pyx in h5py.h5a.AttrID.dtype.__get__()
h5pyh5t.pyx in h5py.h5t.TypeFloatID.py_dtype()
ValueError: Insufficient precision in available types to represent (63, 52, 11, 0, 52)

如果有人知道如何更改值的数据类型或使其能够以相同的精度访问原始值,那就太好了。我实际上需要这些原始值保持原样,理想情况下最多可以保留5位小数(如果需要,可以减少到4位(

感谢您的时间和关注。

有趣的问题。。。我从来没有得到过";精度不足";错误,所以这是我诊断问题的最佳猜测。我怀疑错误是将属性值转换为print语句所需的字符串。该属性可能被保存为意外的数据类型,并且可能需要一些争论才能打印。

首先,我会检查属性semi_angles_rad,以确保您可以访问它。

接下来,我将检查y_dirs上的类型,如下所示:print(type(group.attrs['y_dirs']))。(另外,为了进行比较,我对z_dirs也会这样做。(您可能还需要检查数据类型。一旦你有了这种类型,你就会更好地了解下一步。

这是一个快速示例,它确认当前版本的h5py(3.7(可以创建np.float128属性并读取值。

import numpy as np
import h5py
print(h5py.__version__)
with h5py.File('test.hdf5', 'w') as f:
# This creates 2 attributes of different types:
f.attrs['as_float64'] = 1.0
print(type(f.attrs['as_float64']))
f.attrs['as_float128'] = np.float128(2.0)
print(type(f.attrs['as_float128']))

更新2022-08-03:显示如何使用低级别API访问属性以获得float128值。

with h5py.File('test.hdf5', 'w') as f:
# This creates 2 attributes of arrays of different np.float types:
arr_in = np.array([1.0,2.0,3.0])
f.attrs['as_float64'] = arr_in
arr_in.dtype = np.float128
f.attrs['as_float128'] = arr_in
with h5py.File('test.hdf5', 'r') as f:
# get attribute arrays with with high level API: 
print(type(f.attrs['as_float64']))
print(type(f.attrs['as_float128']))
# get float128 attribute array with with low level API: 
aid = f.attrs.get('as_float128')
print(aid.dtype, aid.shape)
arr_out = np.empty(shape=aid.shape,dytpe=aid.dtype)
aid.read(arr.out)
print(arr_out)

最新更新