【问题标题】:How to select a subset of a dictionary by index?如何按索引选择字典的子集?
【发布时间】:2021-01-29 04:21:31
【问题描述】:

我有一个h5py 文件,其中包含有关数据集的信息。数据集中有n 项和k 键。例如,对于每个项目,我为键 bboxnumber_keypoints 等存储了一个值。由于数据集对我来说太大了,我想从数据集中随机抽样并创建一个较小的 h5py 或 @ 987654327@文件。

比方说,我想对 [1, 6, 16] 的商品进行抽样。然后,我想为所有键实际使用这些索引(我希望很清楚,我正在尝试做什么)。

下面是我的想法:

import h5py
with h5py.File(my_file, "r") as f:
    arr = [1, 6, 16]
    f = {key: value for i, (key, value) in enumerate(f.items()) if i in arr}

很遗憾,这不起作用。有人可以帮我吗?

【问题讨论】:

  • 什么不起作用?你能给出一些示例输入和预期输出吗?

标签: python json dictionary h5py


【解决方案1】:

您可以使用 h5py 指南中称为 fancy indexing 的内容:

假设您有一个数据集 ds,其中包含从 1 到 10 的数字,您希望获取 arr =[2,4,5] 指定的索引。 您可以使用 sub_ds = ds[arr] 获取子集,这将为您提供一个长度为 3 的数组,其中包含 arr 中所需索引的值。

如果你有一个名为 keys 的键数组(只有在你的根目录下没有组,只有数据集时,你才能使用 f.keys()。否则你会得到一个错误),得到什么您希望您可以将代码修改为:

import h5py
with h5py.File(my_file, "r") as f:
    arr = [1, 6, 16]
    f_subset = {key: f[key][arr] for key in keys}

【讨论】:

  • 非常感谢,这样更好! :) 我也不知道支持这种类型的索引,很好
  • @spadel,请注意这两种方法为字典值返回不同的对象类型。使用 Assaf 的方法,它们是(numpy)数组切片,并且您的方法将值作为列表返回。根据您要对这些值执行的操作,这在下游操作中可能重要,也可能不重要。此外,正如 Assaf 所提到的,这仅在文件根级别的所有对象都是数据集(而不是组)时才有效。它还假设所有数据集都具有相同的形状(并且对于列表中的索引具有足够的大小)。
  • @kcw78 你是绝对正确的,这两种数据结构是不可互换的,需要不同的函数来操作和序列化。但是,您可以很容易地将 numpy 数组转换为列表,反之亦然。顺便说一句,如果您想在 hdf5 文件中查找所有数据集键,请查看此线程 stackoverflow.com/questions/44883175/… 我还在那里添加了我自己的答案,它使用一个简单的函数来做到这一点。
  • @Assaf,是的,我熟悉 h5py .visit() 和 .visititems() 方法。我有几篇使用它们的帖子。我怀疑@spadel 的用例是特定于模型的,所以不必担心我提到的问题。对于那些使用更通用数据模式的人,我在这个线程中添加了一个答案,以显示测试数据集及其形状属性的逻辑。
【解决方案2】:

对不起各位,我自己想通了:

import h5py
with h5py.File(my_file, "r") as f:
    arr = [1, 6, 16]
    f_subset = {key: [value for i, value in enumerate(list(f[key])) if i in arr] for key in f.keys()}

这就是我想要的:)

【讨论】:

  • 好吧,这种方法太慢了——每个键有超过 200 万个项目。有谁知道如何加快速度?
【解决方案3】:

如上面的 cmets 中所述,仅当文件根级别的所有对象都是数据集(而不是组)并且数据集具有适合切片列表中索引的形状和大小时,先前的答案才有效。下面的代码显示了使用适当形状的数据集验证和处理节点(键)的逻辑。

import h5py
with h5py.File(my_file, "r") as h5f:
    arr = [1, 6, 16]
    f_subset = dict()
    for key in h5f.keys():
        if isinstance(h5f[key],h5py.Dataset):
            if len(h5f[key].shape) == 1 and h5f[key].shape[0] > max(arr):
                f_subset[key] = h5f[key][arr] 

此处发布的所有 3 个代码示例仅在根级别的数据集上运行。如果需要递归搜索,可以使用 h5py .visit().visititems() 方法扩展此过程以递归查找节点(组和数据集)。还有其他 SO Answers 涵盖了这一点。

【讨论】:

    猜你喜欢
    • 2021-06-03
    • 2020-09-05
    • 2017-03-12
    • 2012-06-01
    • 2011-01-13
    • 2017-11-27
    • 2021-11-01
    • 1970-01-01
    • 2018-05-06
    相关资源
    最近更新 更多