通过HDF5分块方法存储大数据

问题描述 投票:0回答:1

我有 3072 个大小为 1024x1024 的矩阵,所以我的数据集看起来像 1024x1024x3072。这些数据总计 24 GB,这使得无法加载到内存中,因此我希望使用 HDF5 的分块存储方法来通过可加载到内存(128x128x3072)的块进行操作,以便我可以对它们进行操作。问题是,我的代码似乎效率极低,需要超过 12 个小时才能创建一段数据 (1024x1024x300) 的 HDF5 文件。 这是我到目前为止编写的代码

with h5py.File("FFT_Heights.h5", "w") as f: 
   dset = f.create_dataset( "chunked", (1024, 1024, 300), chunks=(128, 128, 300), dtype='complex128'
   ) 
   for ii in tqdm(range(300)):
       dset[ii] = np.load(f'K field {ii}.npy').astype('complex128')

正如您在我的示例代码中看到的,我只从 3072 个矩阵中取出了 300 个,这是因为我试图在运行整个数据之前确保代码适用于较小的数据集。另外,请记住,我的数据很复杂,并且在创建文件时不得损害虚部,因此我事先设置了 dtype。所以,最重要的是,问题在于写入速度。生成的 HDF5 文件构建正确,我已经检查过了,但问题是我需要为 3072 个图像运行此代码,我想知道是否有办法使此文件创建更高效(我已经还尝试了不同的块大小,但在写入速度方面得到了相同的结果)。最后,我正在研究Python。预先感谢!

python file storage hdf5
1个回答
0
投票

您需要修改块大小。尺寸和形状错误。

  1. 首先,它太大了。建议的块大小范围为 10 KiB 到 1 MiB(数据集越大则越大)。根据我的计算,你的是 77 Mib。
  2. 更重要的是,它的形状不适合加载(和读取)图像数组。每个图像的尺寸为 1024x1024,并且您一次加载 1 个图像。对于块形状为 (128, 128, 300),您将必须写入 64 个块(8x8 块)。

我将块修改为

chunks=(1024, 1024, 1)
。这与 1 个图像的形状匹配,因此每次访问图像时都会写入或读取 1 个块。此外,它将块大小减少到 17 MiB。

我运行了加载 400 个 complex128 npy 文件的测试。它在具有 24 GB RAM 的(非常)旧的 Windows 工作站上运行只需 33 秒。注意:加载时间不是线性的。前 250 个文件加载速度很快(0.7 秒内加载 25 个 npy 文件)。文件 250-400 需要更长的时间(3.6 秒内 25 个 npy 文件)。

注意:我必须修改将 npy 文件加载到数据集的行上的数据集索引。我不确定你的索引是如何/为什么起作用的。也许广播对你有用。请参阅下面的代码:

cnt = 400
with h5py.File("FFT_Heights.h5", "w") as h5f: 
   dset = h5f.create_dataset("chunked", (1024, 1024, cnt), 
                             chunks=(1024, 1024, 1), dtype='complex128')     
   total = time.time()
   for ii in range(cnt):
       dset[:,:,ii] = np.load(f'K field {ii}.npy')    
       
print(f'Total elapsed time={time.time()-total:.2f}')       
© www.soinside.com 2019 - 2024. All rights reserved.