问题是为大型hdf5文件重命名组中的所有HDF5数据集

Ric*_*ard 6 python performance hdf5 h5py

我在hdf5中重命名数据集时遇到问题.这个过程非常缓慢.我阅读了一些文档,说明数据集名称只是数据的链接,因此可接受的重命名方法是:

group['new_name'] = group['old_name']
del group['old_name']
Run Code Online (Sandbox Code Playgroud)

但这太慢了(一夜之间只有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]
Run Code Online (Sandbox Code Playgroud)

根据@jpp的建议,我也尝试用以下代码替换最后两行group.move:

group.move(key, new_key)
Run Code Online (Sandbox Code Playgroud)

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

当然有一种方法可以快速完成.数据集名称只是一个符号链接吗?或者重命名是否会导致整个数据集被重写?我该如何重命名HDF5文件中的许多数据集?

ilm*_*nen 1

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

while len(new_key)<tot_digits:
    new_key = '0'+str(new_key)
Run Code Online (Sandbox Code Playgroud)

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

if len(new_key)<tot_digits:
    new_key = (tot_digits-len(new_key))*'0' + new_key
Run Code Online (Sandbox Code Playgroud)

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

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

for key in tqdm(list(group.keys())):
Run Code Online (Sandbox Code Playgroud)