【问题标题】:How to read contents of datasets of a h5py file into a numpy array given a list of keys?如何在给定键列表的情况下将 h5py 文件的数据集内容读入 numpy 数组?
【发布时间】:2017-06-19 22:52:42
【问题描述】:

我的函数的输入是一个 h5py 文件和一个文本文件。文本文件有两列。第一列有一些话语信息,第二列有说话者信息(对于那个话语)。 h5py 文件(使用 create_datasets 创建)的键是话语(文件的第一列)。每个数据集都将有一个固定维度 (600, ) 的 numpy 数组(只有一个)。 h5py 文件的话语比文本文件中的话语多。文本文件中的某些话语可能不存在于 h5py 文件中。

我的函数的预期输出:两个 numpy 数组

第一个数组(我们称之为 X)应该是形状((nutts, 600), dtype='float')

第二个数组(我们称之为 y)的形状应该是 ((nutts,), dtype='int' )

其中 nutts 是(实际)存在于 h5file 中的文本文件的话语数量(nutts

注意:我事先并不知道这些疯子。我必须动态创建 X 和 y。

创建X的方法从上面的描述应该很清楚了:

对于文本文件中的第一个话语,我检查该话语是否作为 h5file 中的键存在。如果存在,我将 numpy 数组(600 维)放入 X 的第一行,然后进行迭代(提醒我事先不知道'nutts',所以我不能用零预先初始化 X。所以我将它们保存为dict 并尝试将 dict 转换为 numpy 数组,一旦我将它们全部到位

关于 y 的更多信息: 所有的 nutts 可能对应于 nspkrs (nspkrs

这是我所做的:

h5f = h5py.File('some.h5', 'r')

import pandas as pd

import numpy as np


def load_data(h5f, src_u2s_list):

    with open(src_u2s_list) as f:

        content = f.read().splitlines()

    utt2ivec = {}
    utt2lbl = {}
    spk2spk_class = {}
    spk_id = -1
    for u2s in content:
        utt, spk = u2s.split()
        if spk not in spk2spk_class.keys():
            spk_id += 1
            spk2spk_class[spk] = spk_id

        if utt in h5f.keys():
            utt2ivec[utt] = h5f[utt][:]
            utt2lbl[utt] = spk2spk_class[spk]
        else:
            print("Utterance {0} does not exist in h5file".format(utt))

    data_X = pd.Series(utt2ivec)
    data_y = pd.Series(utt2lbl)

    return data_X.values, data_y.values

主要考虑:

  1. h5 文件有大约 100,000 个话语,文本文件有大约 70000 个话语。所以这段代码运行非常慢
  2. 我不熟悉使用 h5py 文件。欢迎提出建议或对代码进行整体重组。
  3. 我想避免使用 pandas。
  4. 非常重要:X 和 y 中的话语顺序应该相同。这意味着 X 和 y 的行应该对应于相同的话语。

抱歉,描述太长了。我想把事情说清楚以避免混淆。

提前谢谢你

【问题讨论】:

  • 除了速度,你对utt2ivec adnutt2lbl的创建满意吗?看起来那些是具有数组值的字典。您的描述可能对您来说很清楚,但对于普通观众来说,它看起来很复杂。我们可以举一些具体的例子。

标签: python arrays numpy h5py


【解决方案1】:

通常当我们想将一堆(大小相等的)数组收集到二维数组中时,我们首先将它们附加到一个列表中,然后在最后创建数组:

utt2ilist = []
...
    if utt in h5f.keys():
        utt2ilist.append(h5f[utt][:])
    ...
utt2iarr = np.array(utt2ilist)

我不知道有什么方法可以同时加载多个数据集,至少不知道h5py。您只需要找到相关的key 并照常加载即可。如果您有大量数据集,每个相对较小(600 个元素)的数据集可能需要一些时间。注意数据集的大小是否不同 - 那么结果将是一个对象 dtype 数组,而不是 2d 数组。

我假设spk2spk_class[spk] 可以收集到类似的列表中。

使用这样的列表将按照阅读顺序对它们进行排序。使用字典和 pandas 将按utt 对它们进行索引。借助字典中介,您可能会丢失有关阅读顺序的信息。

我本来打算为spk2spk_class 推荐defaultdict,但您没有计算对象,而只是给它们唯一的ID。

我的猜测是,缓慢来自于仅仅读取大量的话语,而不是来自收集机制本身。但我没有要测试的数据。

【讨论】:

    猜你喜欢
    • 2015-02-24
    • 2019-11-29
    • 1970-01-01
    • 2018-09-29
    • 2018-06-26
    • 1970-01-01
    • 1970-01-01
    • 2010-12-11
    • 2016-01-10
    相关资源
    最近更新 更多