【问题标题】:How to concatenate two numpy arrays in hdf5 format?如何以 hdf5 格式连接两个 numpy 数组?
【发布时间】:2017-10-11 06:47:30
【问题描述】:

我有两个存储在 hdf5 中的 numpy 数组,它们是 每个 44 GB。我需要将它们连接在一起 但需要在磁盘上执行,因为我只有 8gb 内存。 我该怎么做?

谢谢!

【问题讨论】:

  • HDF5 对 numpy 一无所知,因此它不是“numpy 数组”。一次只阅读其中的一部分并将它们连接起来。 [1, 2, 3, 4].concat([5, 6, 7, 8]) 和[1, 2].concat([3, 4]).concat([5, 6]).concat([7, 8])一样,应该可以分块做。
  • 有一个h5py 模块可以从 hdf5 文件中加载数组。它可以分块加载。但是如果你不能同时加载这两个文件,你就不能将它们连接起来或将新的更大的数组写入文件。
  • Combining hdf5 files的可能重复
  • hpaulj,所以如果我的 hdf5 文件是 44 gb,并且我想将它们组合成一个 hdf5 文件,我将需要 88gb 的 ram 临时组合,然后再写回 hdf5 文件?
  • 是的,如果你想用python 来做这件事。我不知道hdf5 实用程序(基于 C 或 Fortran)可以做什么。

标签: numpy hdf5 h5py


【解决方案1】:

相关帖子是在结果文件中获取不同的数据集。在 Python 中这是可能的,但您需要在多个操作中读取和写入数据集。比如说,从文件 1 中读取 1GB,写入输出文件,重复直到从文件 1 中读取所有数据并对文件 2 执行相同操作。您需要直接在适当最终大小的输出文件中声明数据集

d = f.create_dataset('name_of_dataset', shape=shape, dtype=dtype, data=None)

其中 shape 是从数据集中计算出来的,dtype 与数据集中的相匹配。

写信给d: d[i*N:(i+1)N] = d_from_file_1[iN:(i+1)*N]

这应该只将数据集部分加载到内存中。

【讨论】:

    【解决方案2】:

    您要扩展的文件必须具有至少一个无限维度和合理的块大小的可扩展变量。然后您可以轻松地将数据附加到此变量,而 hdf5 文件格式实际上非常适合此类任务。如果追加不起作用,您可能只需要创建一个新文件,这应该不是问题。以下示例将创建两个文件,然后将数据从第二个文件合并到第一个文件。用文件>80G测试,内存使用没有问题。

    import h5py
    import numpy as np
    
    ini_dim1 = 100000
    ini_dim2 = 1000
    
    counter = int(ini_dim1/10)
    dim_extend = int(ini_dim1/counter)
    
    def create_random_dataset(name, dim1, dim2):
        ff1 = h5py.File(name,'w')
        ff1.create_dataset('test_var',(ini_dim1,ini_dim2),maxshape=(None,None),chunks=(10,10))
        for i in range(counter):
            ff1['test_var'][i*dim_extend:(i+1)*dim_extend,:] = np.random.random((dim_extend,ini_dim2))
            ff1.flush()
        ff1.close()
    
    create_random_dataset('test1.h5', ini_dim1, ini_dim2)
    create_random_dataset('test2.h5', ini_dim1, ini_dim2)
    
    ## append second to first
    ff3 = h5py.File('test2.h5','r')
    ff4 = h5py.File('test1.h5','a')
    print(ff3['test_var'])
    print(ff4['test_var'])
    ff4['test_var'].resize((ini_dim1*2,ini_dim2))
    print(ff4['test_var'])
    
    for i in range(counter):
        ff4['test_var'][ini_dim1+i*dim_extend:ini_dim1 + (i+1)*dim_extend,:] = ff3['test_var'][i*dim_extend:(i+1)*dim_extend,:]
        ff4.flush()
    ff3.close()
    ff4.close()
    

    【讨论】:

      猜你喜欢
      • 2014-03-20
      • 2012-03-03
      • 1970-01-01
      • 1970-01-01
      • 2017-08-12
      • 1970-01-01
      • 2015-08-07
      • 1970-01-01
      相关资源
      最近更新 更多