python 3 中的 hdf5 h5py 字符串:使用 (float, string) 设置或编码元组到属性的正确方法
hdf5 h5py strings in python 3: correct way to set or encode tuple with (float, string) to attributes
我知道在 hdf5 中处理字符串似乎很棘手 - 我正在寻找一种正确的方法来将属性设置为数据集,其中属性值采用元组形式,(float/number/numpyarray,字符串).
此外,我需要它在回读时与输入的相同,因为我随后将数据集属性与所需属性的有序字典进行比较。
正确的处理方法是什么?
到目前为止我已经使用
设置了属性
def setallattributes(dataset, dictattributes):
for key, value in dictattributes.items():
tup0 = value[0]
tup1 = value[1].encode('utf-8')
value = (tup0, tup1)
dataset.attrs[key] = value
我正在尝试使用
检查属性是否与所需属性匹配
for datasetname in list(group.keys()):
dataset = f[datasetname]
if dataset.size != 0:
saved_attributes = dataset.attrs.items() #Get (name, value) tuples for all attributes attached to this object. On Py3, it’s a collection or set-like object.
if dict(saved_attributes) == input_attributes: #check attributes match -- both dicts, one ordered one not
datasetnamelist.append(datasetname)
这目前导致尝试比较
{'Rmax': array([b'200.0', b'ld'], dtype='|S32'), 'fracinc': array([b'0.5', b'$\pi$'], dtype='|S32')} == OrderedDict([('Rmin', (0, 'ld')), ('Rmax',(1, 'ld')), ('fracinc',(0.5, r'$\pi$'))])
其中 returns 错误。
http://docs.h5py.org/en/stable/high/attr.html
They may be created from any scalar or NumPy array
data – Value of the attribute; will be put through numpy.array(data)
从元组创建数组:
In [115]: np.array((0, 'ld'))
Out[115]: array(['0', 'ld'], dtype='<U21')
In [116]: np.array((0, b'ld')) # for bytestring
Out[116]: array([b'0', b'ld'], dtype='|S21')
将属性检索为混合类型元组将很棘手。
创建结构化数组(复合数据类型)可能有效:
In [122]: np.array((0, 'ld'), dtype='i,S10')
Out[122]: array((0, b'ld'), dtype=[('f0', '<i4'), ('f1', 'S10')])
In [123]: print(_)
(0, b'ld')
In [124]: __.tolist()
Out[124]: (0, b'ld')
正在将您的字典保存到组中:
In [126]: dd = dict([('Rmin', (0, 'ld')), ('Rmax',(1, 'ld')), ('fracinc',(0.5, r'$\pi$'))])
In [131]: f = h5py.File('attrs.h5','w')
In [132]: g = f.create_group('group')
In [137]: for key in dd:
...: value = list(dd[key])
...: value[1] = value[1].encode('utf-8')
...: value = np.array(tuple(value), dtype='int,S10')
...: g.attrs[key] = value
...:
In [138]: g.attrs
Out[138]: <Attributes of HDF5 object at 140472104481960>
In [139]: list(g.attrs.items())
Out[139]: [('Rmin', (0, b'ld')), ('Rmax', (1, b'ld')), ('fracinc', (0, b'$\pi$'))]
In [140]: g.attrs['fracinc']
Out[140]: (0, b'$\pi$')
这显示为一个元组,但实际上是一个 numpy void
。我们需要 tolist()
或 item()
来得到一个可以与另一个元组进行比较的元组:
In [142]: g.attrs['Rmin'].tolist()==(0,b'ld')
Out[142]: True
将此与 dd['Rmin']
进行比较需要将一个字符串值转换为 /from bytestring。
In [146]: def foo(value):
...: value = list(value)
...: value[1] = value[1].encode('utf-8')
...: return tuple(value)
...:
In [147]: dd1 = {key:foo(value) for key,value in dd.items()}
In [148]: dd1
Out[148]: {'Rmin': (0, b'ld'), 'Rmax': (1, b'ld'), 'fracinc': (0.5, b'$\pi$')}
In [149]: g.attrs['Rmin'].tolist()==dd1['Rmin']
Out[149]: True
这与 dd1
不匹配,因为我用 int
字段保存了它('fracint' 有一个浮点数):
In [155]: {key:value.item() for key,value in g.attrs.items()}
Out[155]: {'Rmin': (0, b'ld'), 'Rmax': (1, b'ld'), 'fracinc': (0, b'$\pi$')}
如果我将 foo
更改为 int(value[0])
,字典就会匹配。
所以如果你需要做这种匹配,你需要通过你(和h5py
)为保存的值做的相同类型的处理来传递测试用例。
我猜测了您的字典定义,并尽我所能重新创建了您的流程。
当您使用元组保存字典时,值将作为字符串数组存储(和检索)(反映在上面输出的 dtype 中)。
您将必须解构数组并转换每一项以匹配原始数据。因此,此过程将特定于保存的数据类型——我认为不可能有通用方法来提取和测试转换为字符串数组的元组。
解法:
import h5py
def setallattributes(dataset, dictattributes):
for key, value in dictattributes.items():
tup0 = value[0]
tup1 = value[1].encode('utf-8')
value = (tup0, tup1)
dataset.attrs[key] = value
with h5py.File('SO_58064282.h5', 'w') as h5f:
ds = h5f['/']
input_attributes = { 'Rmin': (0, 'ld'),
'Rmax': (1, 'ld'), 'fracinc': (0.5, r'$\pi$') }
print ('Input:\n:',input_attributes)
setallattributes (ds, input_attributes)
saved_attributes = ds.attrs.items()
saved_attrs_dict = {}
print ('Saved Attributes:')
for item in saved_attributes:
print (item)
saved_attrs_dict.update( {item[0] :
(float(item[1][0]), item[1][1].decode('utf-8')) })
print ('Converted to Dict:\n:',dict(saved_attrs_dict))
if saved_attrs_dict == input_attributes:
#check attributes match -- both dicts, one ordered one not
print ('Saved = Input')
else:
print ('mismatched dictionaries')
print ('Done')
我知道在 hdf5 中处理字符串似乎很棘手 - 我正在寻找一种正确的方法来将属性设置为数据集,其中属性值采用元组形式,(float/number/numpyarray,字符串).
此外,我需要它在回读时与输入的相同,因为我随后将数据集属性与所需属性的有序字典进行比较。
正确的处理方法是什么?
到目前为止我已经使用
设置了属性 def setallattributes(dataset, dictattributes):
for key, value in dictattributes.items():
tup0 = value[0]
tup1 = value[1].encode('utf-8')
value = (tup0, tup1)
dataset.attrs[key] = value
我正在尝试使用
检查属性是否与所需属性匹配 for datasetname in list(group.keys()):
dataset = f[datasetname]
if dataset.size != 0:
saved_attributes = dataset.attrs.items() #Get (name, value) tuples for all attributes attached to this object. On Py3, it’s a collection or set-like object.
if dict(saved_attributes) == input_attributes: #check attributes match -- both dicts, one ordered one not
datasetnamelist.append(datasetname)
这目前导致尝试比较
{'Rmax': array([b'200.0', b'ld'], dtype='|S32'), 'fracinc': array([b'0.5', b'$\pi$'], dtype='|S32')} == OrderedDict([('Rmin', (0, 'ld')), ('Rmax',(1, 'ld')), ('fracinc',(0.5, r'$\pi$'))])
其中 returns 错误。
http://docs.h5py.org/en/stable/high/attr.html
They may be created from any scalar or NumPy array
data – Value of the attribute; will be put through numpy.array(data)
从元组创建数组:
In [115]: np.array((0, 'ld'))
Out[115]: array(['0', 'ld'], dtype='<U21')
In [116]: np.array((0, b'ld')) # for bytestring
Out[116]: array([b'0', b'ld'], dtype='|S21')
将属性检索为混合类型元组将很棘手。
创建结构化数组(复合数据类型)可能有效:
In [122]: np.array((0, 'ld'), dtype='i,S10')
Out[122]: array((0, b'ld'), dtype=[('f0', '<i4'), ('f1', 'S10')])
In [123]: print(_)
(0, b'ld')
In [124]: __.tolist()
Out[124]: (0, b'ld')
正在将您的字典保存到组中:
In [126]: dd = dict([('Rmin', (0, 'ld')), ('Rmax',(1, 'ld')), ('fracinc',(0.5, r'$\pi$'))])
In [131]: f = h5py.File('attrs.h5','w')
In [132]: g = f.create_group('group')
In [137]: for key in dd:
...: value = list(dd[key])
...: value[1] = value[1].encode('utf-8')
...: value = np.array(tuple(value), dtype='int,S10')
...: g.attrs[key] = value
...:
In [138]: g.attrs
Out[138]: <Attributes of HDF5 object at 140472104481960>
In [139]: list(g.attrs.items())
Out[139]: [('Rmin', (0, b'ld')), ('Rmax', (1, b'ld')), ('fracinc', (0, b'$\pi$'))]
In [140]: g.attrs['fracinc']
Out[140]: (0, b'$\pi$')
这显示为一个元组,但实际上是一个 numpy void
。我们需要 tolist()
或 item()
来得到一个可以与另一个元组进行比较的元组:
In [142]: g.attrs['Rmin'].tolist()==(0,b'ld')
Out[142]: True
将此与 dd['Rmin']
进行比较需要将一个字符串值转换为 /from bytestring。
In [146]: def foo(value):
...: value = list(value)
...: value[1] = value[1].encode('utf-8')
...: return tuple(value)
...:
In [147]: dd1 = {key:foo(value) for key,value in dd.items()}
In [148]: dd1
Out[148]: {'Rmin': (0, b'ld'), 'Rmax': (1, b'ld'), 'fracinc': (0.5, b'$\pi$')}
In [149]: g.attrs['Rmin'].tolist()==dd1['Rmin']
Out[149]: True
这与 dd1
不匹配,因为我用 int
字段保存了它('fracint' 有一个浮点数):
In [155]: {key:value.item() for key,value in g.attrs.items()}
Out[155]: {'Rmin': (0, b'ld'), 'Rmax': (1, b'ld'), 'fracinc': (0, b'$\pi$')}
如果我将 foo
更改为 int(value[0])
,字典就会匹配。
所以如果你需要做这种匹配,你需要通过你(和h5py
)为保存的值做的相同类型的处理来传递测试用例。
我猜测了您的字典定义,并尽我所能重新创建了您的流程。 当您使用元组保存字典时,值将作为字符串数组存储(和检索)(反映在上面输出的 dtype 中)。
您将必须解构数组并转换每一项以匹配原始数据。因此,此过程将特定于保存的数据类型——我认为不可能有通用方法来提取和测试转换为字符串数组的元组。
解法:
import h5py
def setallattributes(dataset, dictattributes):
for key, value in dictattributes.items():
tup0 = value[0]
tup1 = value[1].encode('utf-8')
value = (tup0, tup1)
dataset.attrs[key] = value
with h5py.File('SO_58064282.h5', 'w') as h5f:
ds = h5f['/']
input_attributes = { 'Rmin': (0, 'ld'),
'Rmax': (1, 'ld'), 'fracinc': (0.5, r'$\pi$') }
print ('Input:\n:',input_attributes)
setallattributes (ds, input_attributes)
saved_attributes = ds.attrs.items()
saved_attrs_dict = {}
print ('Saved Attributes:')
for item in saved_attributes:
print (item)
saved_attrs_dict.update( {item[0] :
(float(item[1][0]), item[1][1].decode('utf-8')) })
print ('Converted to Dict:\n:',dict(saved_attrs_dict))
if saved_attrs_dict == input_attributes:
#check attributes match -- both dicts, one ordered one not
print ('Saved = Input')
else:
print ('mismatched dictionaries')
print ('Done')