如何通过索引 select 字典的子集?

How to select a subset of a dictionary by index?

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

比方说,我想对项目 [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}

不幸的是,这不起作用。有人可以帮我吗?

对不起各位,我只是自己想出来的:

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()}

这就是我想要的:)

你可以使用 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}

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

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 答案。