【问题标题】:Storing multidimensional variable length array with h5py使用 h5py 存储多维变长数组
【发布时间】:2017-07-28 06:14:02
【问题描述】:

我正在尝试使用以下过程将可变长度数组列表存储在 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

【问题讨论】:

    标签: numpy hdf5 h5py


    【解决方案1】:

    你的代码的本质是:

    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?如果所有元素都是相同形状和 dtype 的数组,它将产生一个更高维的数组。如果它们的形状不同,它将生成一个具有 object dtype 的一维数组。鉴于错误信息,我怀疑是后者。

    我已经回答了几个vlen 的问题,但没有经常使用它

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

    我隐约记得h5 数组的“参差不齐”维度只能是 1d。因此,包含不同维度的一维浮点数组的 phn_mfccs 对象数组可能会起作用。

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

    2015 年关于 vlen 数组的帖子

    Inexplicable behavior when using vlen with h5py

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

    一维参差不齐的数组示例

    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 对象必须是一维浮点数组。

    【讨论】:

    • 感谢您清理代码(我将编辑详细信息,因为您提到那里有很多无关的东西)。 np.array(phn_mfccs) 确实产生了一个具有维度([我们追加的次数])的 dtype 'O' 数组。每个phn_mfcc 元素都有不同的维度。有没有办法用 HDF 存储这样的东西?如果我尝试在 create_dataset 的参数中明确指定我想要一个 dtype='O' 的数据集,它会抛出我上面提到的错误。
    • 外部数组phn_mfcc可以是对象dtype,但我认为对象本身需要是一维数组。我会做实验。
    • 那么它最终是没有希望了吗?你会推荐另一个库来处理这个特定的数据集吗?
    • 我可以尝试展平数组,并将某种形状信息存储在属性或其他数据集中。
    猜你喜欢
    • 2017-05-18
    • 2017-05-16
    • 2015-12-08
    • 2013-05-17
    • 2014-12-03
    • 2014-02-26
    • 2012-03-07
    • 2016-05-12
    • 1970-01-01
    相关资源
    最近更新 更多