用h5py存储多维变长数组

Storing multidimensional variable length array with 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',它会吐出类似 "Object dtype 'O' has no native HDF equivalent."

的错误

理想情况下,我希望 mfccs_out['phn_mfccs'][i] 包含我附加到列表 phn_mfccs.

的第 i 个 phn_mfcc

你的代码的本质是:

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

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

我不完全确定 create_dataset 在给定数组列表时会做什么。它可以将其包装在 np.array.

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

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

我已经回答了一些 vlen 个问题,但还没有使用它很多

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

依稀记得h5数组的'ragged'维度只能是1d。因此,包含不同维度的一维浮点数组的 phn_mfccs 对象数组可能会起作用。

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

A 2015 post vlen 数组

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)

如果我尝试将二维数组写入 dataset,我会收到错误消息

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

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