重命名组中的所有HDF5数据集以获取较大的HDF5文件时出现问题

时间:2018-10-31 14:38:58

标签: python performance hdf5 h5py

我在重命名hdf5中的数据集时遇到问题。该过程非常缓慢。我阅读了一些文档,指出数据集名称仅是数据的链接,因此,可以接受的重命名方法是:

group['new_name'] = group['old_name']
del group['old_name']

但这太慢了(整夜只能完成5%的运行),这让我觉得我的过程是完全错误的。

我正在使用python h5py,这是我的慢代码:

# Open file
with h5py.File('test.hdf5') as f:

    # Get all top level groups
    top_keys = [key for key in f.keys()]

    # Iterate over each group
    for top_key in top_keys:
        group = f[top_key]
        tot_digits = len(group)

        #Rename all datasets in the group (pad with zeros)
        for key in tqdm(group.keys()):
            new_key = str(key)
            while len(new_key)<tot_digits:
                new_key = '0'+str(new_key)
            group[new_key] = group[key]
            del group[key]

根据@jpp的建议,我还尝试用group.move替换最后两行:

group.move(key, new_key)

但是这种方法同样慢。我有几组具有相同数量的数据集,但是每组都有不同大小的数据集。数据集最多(字节最多)的组似乎重命名了最慢的组。

当然,有一种方法可以快速执行此操作。数据集名称仅仅是符号链接吗?还是重命名本身会导致整个数据集被重写?我应该如何重命名HDF5文件中的许多数据集?

2 个答案:

答案 0 :(得分:1)

一个可能的罪魁祸首,至少在顶层密钥下有大量组的情况下,是您以非常低效的方式创建新名称。代替

while len(new_key)<tot_digits:
    new_key = '0'+str(new_key)

您应该像这样生成新密钥:

if len(new_key)<tot_digits:
    new_key = (tot_digits-len(new_key))*'0' + new_key

这样,您就不必为需要添加的每个额外数字创建新的字符串对象。

尽管我无法确认这一点,但调用group.keys()可能会返回一个迭代器,该迭代器将使用您添加的新键名进行填充,因为您是在迭代键时修改组的。一个标准的python迭代器会抛出RuntimeError,但是很清楚hf5py是否会做同样的事情。为了确保您没有这个问题,可以简单地确保预先创建一个键列表。

for key in tqdm(list(group.keys())):

答案 1 :(得分:0)

这个怎么样?难道该组的查找要比简单的迭代花费更长的时间?我做了一些优化-由于我没有测试文件,因此我无法真正尝试一下。

# Open file
with h5py.File('test.hdf5') as f:

    # Iterate over each group
    for top_key, group in f.items():
        #Rename all datasets in the group (pad with zeros)
        for key in tqdm(group.keys()):
            new_key = ("{:0<" + str(len(group)) + "}").format(str(key))
            group.move(key, new_key)