h5py 不支持 NumPy dtype('U') (Unicode),pandas 不支持 NumPy dtype('O')



我正在尝试创建一个.h5文件,其中包含.dat文件中的数据集。首先,我使用numpy:来处理这个问题

import numpy as np
import h5py
filename = 'VAL220408-invparms.dat'
datasetname = 'EM27_104_COCCON_VAL/220408'
dtvec = [float for i in range(149)] #My data file have 149 columns
dtvec[1] = str
dtvec[2] = str #I specify the dtype of the second and third column
dataset = np.genfromtxt(filename,skip_header=0,names=True,dtype=dtvec)
fh5 = h5py.File('my_data.h5', 'w')
fh5.create_dataset(datasetname,data=dataset)
fh5.flush()
fh5.close()

但当运行时,我得到错误:

TypeError:没有dtype的转换路径:dtype('<U')

如果我不指定dtype,一切都很好,数据集有序,数值正确,只有第二列和第三列的值为NaN;我不想那样。

我发现h5py不支持Numpy对字符串的编码,所以我认为使用panda中的数据帧可以工作。我使用熊猫的代码是这样的:

import numpy as np
import pandas as pd
filename = 'VAL220408-invparms.dat'
datasetname = 'EM27_104_COCCON_VAL/220408'
df = pd.read_csv(filename,header=0,sep="s+")
fh5 = h5py.File('my_data.h5', 'w')
fh5.create_dataset(datasetname,data=df)
fh5.flush()
fh5.close()

但后来我得到了错误:

TypeError:对象dtype dtype('O')没有本地HDF5等效

然后我发现pandas有一个函数可以将数据帧转换为.h5文件,所以我使用了我制作的h5py库:

df.to_hdf('my_data.h5','datasetname',format='table',mode='a')

但是.h5文件中的许多表中的数据都搞砸了。

我真的很想得到一些帮助,只得到第二列和第三列的数据,就像它真的一样,一个str.

我使用的是Python 3.8

非常感谢您的阅读。

我刚刚想明白了。

在h5py文档中,他们说要使用将字符串指定为h5py字符串

h5py.string_dtype(encoding='utf-8', length=None)

所以在我的第一段代码中,我放了:

dtvec[1] = h5py.string_dtype(encoding='utf-8', length=None) 
dtvec[2] = h5py.string_dtype(encoding='utf-8', length=None) 

希望这对阅读这个问题的人有帮助。

为了澄清,这个问题与NumPy的Unicode字符串类型的处理有关。HDF5(和h5py)不支持这种类型。这里的详细信息:h5py:NumPy的U型怎么样?

当您将字符串字段(列)定义为str时,您将获得Unicode值。您可以使用以下工具进行验证:

dtvec = [float for i in range(149)] #My data file have 149 columns
dtvec[1] = str
dtvec[2] = str #I specify the dtype of the second and third column
dataset = np.genfromtxt(filename,names=True,dtype=dtvec)
print(dataset.dtype)

输出将如下所示。<U字段是您具有Unicode值的地方。字段"str1"one_answers"str2"中的Unicode值导致了原始错误。

[('float1', '<f8'), ('str1', '<U'), ('str2', '<U'), ('float2', '<f8').....]

当您修改为使用h5py.string_dtype()时,h5py知道如何将Unicode值转换为字节字符串(HDF5和h5py支持这些值)。设置length=None允许映射到NumPy对象(字节字符串数组)的可变长度字符串。详细信息:h5py:可变长度字符串

dtvec[1] = h5py.string_dtype(encoding='utf-8', length=None) 
dtvec[2] = h5py.string_dtype(encoding='utf-8', length=None) 
dataset = np.genfromtxt(filename,names=True,dtype=dtvec)
print(dataset.dtype)

输出将如下所示。O字段是有字符串的地方(作为字节字符串的数组):

[('float1', '<f8'), ('str1', 'O'), ('str2', 'O'), ('float2', '<f8').....]

您还可以定义固定长度的字节字符串。(我用了5,因为这是我测试数据的大小。)

dtvec[1] = h5py.string_dtype(encoding='utf-8', length=5) 
dtvec[2] = h5py.string_dtype(encoding='utf-8', length=5) 
# alternate definition, same result
# dtvec[1] = 'S5'
# dtvec[2] = 'S5'
dataset = np.genfromtxt(filename,names=True,dtype=dtvec)
print(dataset.dtype)

输出将如下所示。S5字段是有字节字符串的地方:

[('float1', '<f8'), ('str1', 'S5'), ('str2', 'S5'), ('float2', '<f8').....]

作为np.genfromtxt()的旁白,您不必定义数据类型。如果设置dtype=None,则每列的数据类型将由其内容(单独)确定。当您事先不知道数据类型时,这很方便。以下是您的数据示例:

dataset = np.genfromtxt(filename,names=True,dtype=None)
print(dataset.dtype)

输出将如下所示。我没有设置上面的encoding=参数,所以获取字符串字节值。当你这样做的时候,np.genfromtxt()会发出VisibleDeprecationWarning。但是,你可以将这些数据写入HDF5。

[('float1', '<f8'), ('str1', 'S5'), ('str2', 'S5'), ('float2', '<f8').....]

最新更新