使用h5py存储多维可变长度数组

时间:2017-03-07 21:13:09

标签: numpy hdf5 h5py

我尝试使用以下过程在HDF文件中存储可变长度数组列表:

phn_mfccs = []

# Import wav files
for waveform in files:
    phn_mfcc = mfcc(waveform) # produces a variable length multidim array of the shape (x, 13, 1)              

    # Add MFCC and label to dataset
    # phn_mfccs has dimension (len(files),)
    # phn_mfccs[i] has variable dimension ([# of frames in ith segment] (variable), 13, 1)
    phn_mfccs.append(phn_mfcc) 

dt = h5py.special_dtype(vlen=np.dtype('float64'))
mfccs_out.create_dataset('phn_mfccs', data=phn_mfccs, dtype=dt)

看起来我的数据类型并没有结果 - 而不是包含多维数组的mfccs_out数据集的每个元素,它只包含一维数组。例如如果我追加的第一个phn_mfcc具有尺寸(59,13,1),则mfccs_out['phn_mfccs'][0]具有尺寸(59,)。 我怀疑是因为我只是使用了float64数据类型,而我需要一些其他数组的数组?但是,如果我没有指定数据集或尝试使用dtype='O',则会发出错误,例如"对象dtype' O'没有本地HDF等价物。"

理想情况下,我希望mfccs_out['phn_mfccs'][i]包含我附加到列表phn_mfcc的第phn_mfccs条。

1 个答案:

答案 0 :(得分:0)

您的代码的本质是:

phn_mfccs = []
<loop several layers>
    phn_mfcc = <some sort of array expanded by one dimension>
    phn_mfccs.append(phn_mfcc) 

循环结束时phn_mfccs是一个数组列表。我无法从代码中分辨出dtype和形状是什么。或者列表中的每个元素是否不同。

在给出数组列表时,我并不完全确定create_dataset的作用。它可以将其包装在np.array

mfccs_out.create_dataset('phn_mfccs', data=phn_mfccs, dtype=dt)

np.array(phn_mfccs)会产生什么?形状,dtype?如果所有元素都是相同形状和dtype的数组,它将产生更高维数组。如果它们的形状不同,它将产生一个带有对象dtype的1d数组。鉴于错误信息,我怀疑后者。

我已经回答了几个vlen个问题,但很多时候没有用过这个问题

http://docs.h5py.org/en/latest/special.html

我隐约记得那个“衣衫褴褛的&#39; h5数组的维度只能是1d。因此,包含不同维度的1d浮点数组的phn_mfccs对象数组可能有效。

我可能会想出一个简单的例子。我建议你构建一个更简单的问题,我们可以复制粘贴和体验。我们不需要知道您如何从目录中读取数据。我们只需要了解您要编写的数组(列表)的内容。

关于vlen数组的2015年帖子

Inexplicable behavior when using vlen with h5py

H5PY - How to store many 2D arrays of different dimensions

1d参差不齐的数组示例

In [24]: f = h5py.File('vlen.h5','w')
In [25]: dt = h5py.special_dtype(vlen=np.dtype('float64'))
In [26]: dataset = f.create_dataset('vlen',(4,), dtype=dt)
In [27]: dataset.value
Out[27]: 
array([array([], dtype=float64), array([], dtype=float64),
       array([], dtype=float64), array([], dtype=float64)], dtype=object)
In [28]: for i in range(4):
    ...:     dataset[i]=np.arange(i+3)

In [29]: dataset.value
Out[29]: 
array([array([ 0.,  1.,  2.]), array([ 0.,  1.,  2.,  3.]),
       array([ 0.,  1.,  2.,  3.,  4.]),
       array([ 0.,  1.,  2.,  3.,  4.,  5.])], dtype=object)

如果我尝试将2d数组写入dataset,我会收到错误

OSError: Can't prepare for writing data (Src and dest data spaces have different sizes)

dataset本身可能是多维的,但vlen对象必须是1d浮点数组。