与 h5py 和 create_dataset 相关的问题
Posted
技术标签:
【中文标题】与 h5py 和 create_dataset 相关的问题【英文标题】:problem related to h5py and create_dataset 【发布时间】:2021-12-22 07:12:57 【问题描述】:也许这个问题很愚蠢,但到目前为止我还没有找到解决方案。 我收到了来自其他人的代码,他可能正在使用与我不同的集合(例如 Python 2 而不是 3 等)。 所以我做了一些小改动以使事情正常进行,但我陷入了与 h5py 相关的一个可能简单的问题。
它崩溃的代码部分如下所示:
labels_ALL = ['ionic_str','psi0','psi1','psi2','psid','zeta','sig0','sig1','sig2','sigd','sig0_eq','sig1_eq','sig2_eq','sigd_eq','ch_bal_EDL','ch_bal_aq', 'sum_resid']
units_ALL = ['(mol/L)','(V)','(V)','(V)','(V)','(V)','(C/m**2)','(C/m**2)','(C/m**2)','(C/m**2)','(mol(eq))','(mol(eq))','(mol(eq))','(mol(eq))','(C/m**2)','(mol(eq)/L)',' ']
for i in range(len(Labels)):
labels_ALL.append(Labels[i])
units_ALL.append('(mol/L)')
base.create_dataset('Labels', data=labels_ALL)
base.create_dataset('Units', data=units_ALL)
问题似乎出在base.create_dataset:
Traceback (most recent call last):
File "C:\Users\DaniJ\Documents\PostDoc_Jena\Trips, Conf, etc\Sinfonia Workshop\Exercise_1\exercise_1_SINFONIA_for_One\NR_chem_SINGLE_NoEu.py", line 252, in <module>
base.create_dataset('Labels', data=labels_ALL)
File "C:\Users\DaniJ\anaconda3\lib\site-packages\h5py\_hl\group.py", line 136, in create_dataset
dsid = dataset.make_new_dset(self, shape, dtype, data, **kwds)
File "C:\Users\DaniJ\anaconda3\lib\site-packages\h5py\_hl\dataset.py", line 118, in make_new_dset
tid = h5t.py_create(dtype, logical=1)
File "h5py\h5t.pyx", line 1634, in h5py.h5t.py_create
File "h5py\h5t.pyx", line 1656, in h5py.h5t.py_create
File "h5py\h5t.pyx", line 1717, in h5py.h5t.py_create
TypeError: No conversion path for dtype: dtype('<U10')
变量 base 似乎是一个 h5py._hl.files.File 变量。
有人可以解决这个问题吗?
谢谢
最好的问候, 丹妮
【问题讨论】:
错误信息 (No conversion path for dtype: dtype('<U10')
) 指的是 HDF5(和 h5py)不支持的 Unicode 字符。您必须在保存之前将 Unicode 转换为字节字符串。您的代码未显示 labels
值的分配,因此我无法重现该问题。如果我注释掉 for i in range():
循环,代码就可以工作,并且只将 labels_ALL
和 units_ALL
的原始值保存到数据集中。
标签基本上是一个字符串列表,例如Labels = ['H+','Na+','Cl-','OH-','>SOH_x','>SO-_x','>SONa_x','>SOH2+_x','>SOH2Cl_x','>SOH_y','>SO-_y','>SONa_y']
嗯...不是我对Labels
的期望。 :-( 如果 Labels
是 NumPy 字符串数组,您将收到 dtype('<U10')
错误。当我添加该行(并包含 for
循环)时,您的代码按预期工作。如果我转换,我可以重现该错误List 到 NumPy 数组。
【参考方案1】:
你的问题解决了吗?我 99.9% 确定它与您的 Labels
数据有关——可能它位于 NumPy 数组而不是列表中。我写了 3 个简短的例子来说明区别。
-
第一个代码段使用 List 并成功创建
文件
SO_69900543_1.h5
中的数据集。
第二个代码段重现了您的错误。它转换列表
到 NumPy 数组然后在尝试创建数据集时失败
在文件SO_69900543_2.h5
。请注意,它给出了相同的错误
您遇到的消息:TypeError: No conversion path for dtype: dtype('<U10')
。
第三个代码段显示如何将numpy.str_
元素修改为str
(解决段#2 中的问题)。请注意,每个Labels
的值在添加到Labels_All
之前都会使用str()
进行转换。
也许这会帮助您找到(并解决)您的 Unicode 数据问题。
代码段 1(有效):
Labels = ['H+','Na+','Cl-','OH-','>SOH_x','>SO-_x','>SONa_x','>SOH2+_x','>SOH2Cl_x','>SOH_y','>SO-_y','>SONa_y']
labels_ALL = ['ionic_str','psi0','psi1','psi2','psid','zeta','sig0','sig1','sig2','sigd','sig0_eq','sig1_eq','sig2_eq','sigd_eq','ch_bal_EDL','ch_bal_aq', 'sum_resid']
units_ALL = ['(mol/L)','(V)','(V)','(V)','(V)','(V)','(C/m**2)','(C/m**2)','(C/m**2)','(C/m**2)','(mol(eq))','(mol(eq))','(mol(eq))','(mol(eq))','(C/m**2)','(mol(eq)/L)',' ']
for i in range(len(Labels)):
labels_ALL.append(Labels[i])
units_ALL.append('(mol/L)')
with h5py.File('SO_69900543_1.h5','w') as base:
base.create_dataset('Labels', data=labels_ALL)
base.create_dataset('Units', data=units_ALL)
代码段 2(返回 TypeError):
Labels = ['H+','Na+','Cl-','OH-','>SOH_x','>SO-_x','>SONa_x','>SOH2+_x','>SOH2Cl_x','>SOH_y','>SO-_y','>SONa_y']
# Convert Labels List to NumPy array
# This will trigger the error when creating the dataset
Labels = np.array(Labels)
labels_ALL = ['ionic_str','psi0','psi1','psi2','psid','zeta','sig0','sig1','sig2','sigd','sig0_eq','sig1_eq','sig2_eq','sigd_eq','ch_bal_EDL','ch_bal_aq', 'sum_resid']
units_ALL = ['(mol/L)','(V)','(V)','(V)','(V)','(V)','(C/m**2)','(C/m**2)','(C/m**2)','(C/m**2)','(mol(eq))','(mol(eq))','(mol(eq))','(mol(eq))','(C/m**2)','(mol(eq)/L)',' ']
for i in range(len(Labels)):
labels_ALL.append(Labels[i])
units_ALL.append('(mol/L)')
for i in range(len(labels_ALL)):
print(i, type(labels_ALL[i]), type(units_ALL[i]))
with h5py.File('SO_69900543_2.h5','w') as base:
base.create_dataset('Labels', data=labels_ALL)
base.create_dataset('Units', data=units_ALL)
代码段 3(有效):
Labels = ['H+','Na+','Cl-','OH-','>SOH_x','>SO-_x','>SONa_x','>SOH2+_x','>SOH2Cl_x','>SOH_y','>SO-_y','>SONa_y']
# Convert Labels List to NumPy array
# This will trigger the error when creating the dataset if not modified
Labels = np.array(Labels)
labels_ALL = ['ionic_str','psi0','psi1','psi2','psid','zeta','sig0','sig1','sig2','sigd','sig0_eq','sig1_eq','sig2_eq','sigd_eq','ch_bal_EDL','ch_bal_aq', 'sum_resid']
units_ALL = ['(mol/L)','(V)','(V)','(V)','(V)','(V)','(C/m**2)','(C/m**2)','(C/m**2)','(C/m**2)','(mol(eq))','(mol(eq))','(mol(eq))','(mol(eq))','(C/m**2)','(mol(eq)/L)',' ']
for i in range(len(Labels)):
# use str() to convert from 'numpy.str_' to 'str'
labels_ALL.append(str(Labels[i]))
units_ALL.append('(mol/L)')
for i in range(len(labels_ALL)):
print(i, type(labels_ALL[i]), type(units_ALL[i]))
with h5py.File('SO_69900543_2.h5','w') as base:
base.create_dataset('Labels', data=labels_ALL)
base.create_dataset('Units', data=units_ALL)
【讨论】:
谢谢,太完美了!! 你好丹尼尔。很高兴这有帮助。如果它解决了您的问题,请检查已接受的答案以表明它是解决方案。问候。以上是关于与 h5py 和 create_dataset 相关的问题的主要内容,如果未能解决你的问题,请参考以下文章