Numpy 如何在内存中加载大型h5文件?
我有一个大的h5文件,带有HDFS中的5维numpy数组。文件大小约为130Gb。我在加载文件时遇到内存问题,进程因OOM错误而终止,即使机器有256Gb RAM。如何将文件分块写入并分块加载?我环顾四周,发现h5py提供了这样的方法来对数据集进行分块,但是如何将数据分块加载回数据集呢?如果文件驻留在HDFS中,它也可以工作吗Numpy 如何在内存中加载大型h5文件?,numpy,hdfs,hdf5,h5py,chunking,Numpy,Hdfs,Hdf5,H5py,Chunking,我有一个大的h5文件,带有HDFS中的5维numpy数组。文件大小约为130Gb。我在加载文件时遇到内存问题,进程因OOM错误而终止,即使机器有256Gb RAM。如何将文件分块写入并分块加载?我环顾四周,发现h5py提供了这样的方法来对数据集进行分块,但是如何将数据分块加载回数据集呢?如果文件驻留在HDFS中,它也可以工作吗 dset = f.create_dataset("Images2", (100,480,640), 'f', chunks=True) 想法是分批加
dset = f.create_dataset("Images2", (100,480,640), 'f', chunks=True)
想法是分批加载文件,以减少I/O时间和内存问题。任何帮助都将不胜感激。HDF5中的分块意味着数据不是连续存储的,而是分块存储的。 请参阅此处的信息: -->所以这对你的问题没有帮助 解决方案可能是您自己构建一个函数来分块加载数据。 例如,我这样做是为了将数据分块:
def get_chunked(data, chunk_size=100):
for i in give_chunk(len(data), chunk_size):
chunked_array = data[i]
yield chunked_array
def give_chunk(length, chunk_size):
it = iter(range(length))
while True:
chunk = list(itertools.islice(it, chunk_size))
if not chunk:
break
yield chunk
要将数据写入HDF5,可以先创建数据集,然后通过切片写入数据块,请参阅h5py文档:
关于HDF5的基本知识,我真的可以推荐这本书:上面的答案和评论中提到了两个类似(但不同)的h5py I/O概念:
- HDF5分块用于启用分块I/O以提高性能。如果在试图读取内存不足的大型数据集时出现OOM错误,分块可能没有帮助
- NumPy样式切片用于将数据片段从驱动器读取到内存(或将数据片段写入驱动器)。在读取非常大的文件时,切片是避免OOM错误的关键
- 此外,在创建非常大的数据集时,通常需要 它可以调整大小。您可以分配初始大小,然后使用“.resize()”方法增加磁盘上的大小
import numpy as np
import h5py
with h5py.File('SO_64645940.h5','w') as h5w:
img_ds = h5w.create_dataset('Images', shape=(100,480,640), dtype='f', maxshape=(None,480,640),chunks=(10,480,640))
next_img_row = 0
arr = np.random.random(100*480*640).reshape(100,480,640)
for cnt in range(1,10):
# print(cnt,img_ds.len(),next_img_row)
if img_ds.len() == next_img_row :
img_ds.resize(100*cnt,axis=0)
print('new ds size=',img_ds.len())
h5w['Images'][next_img_row:next_img_row+100] = arr
next_img_row += 100
with h5py.File('SO_64645940.h5','r') as h5r:
for cnt in range(10):
print('get slice#',str(cnt))
img_arr = h5r['Images'][cnt*100:(cnt+1)*100]
即使没有块,也可以加载片,例如
dset[33]
或dset[22:55]
。这在h5py
文档中有说明。