我有一个具有多个维度(x、y、通道、z、时间步长)的数组。但是,原始数据作为 (x, y, 通道) 的单个堆栈存储在 TIFF 图像中,具有 z * 时间步长帧。
最后,Pillow 的 Image.getdata() 函数返回一个需要重新整形的一维数组对象。
如果数据集太大而无法放入内存,那么将其读入 HDF5 的最佳方法是什么?是否可以在将数组写入 HDF5 后对其进行整形,或者以一种自动填充数组的方式写入一维数据(即写入 x 变化最快,y 第二快等)更新:类似于numpy.ndarray.flat将是理想的。
到目前为止,这是我尝试过的(img 是 PIL.Image,dset 是 h5py 数据集):
1)读取单个帧。这种方法太慢了,因为 1000 帧中的 300MB 需要大约 20 分钟。大部分时间都花在了 dset[] = 一个调用上。
for i in range(0, img_layers):
img.seek(i)
a = numpy.array(img.getdata(), dtype=dtype) # a.shape = (sx * sz * channels,)
a.resize(sx, sy, channels)
z = i % sz
frame = i // sz
dset[..., z, frame] = a
2)不完整:分块阅读。这要快得多(同一数据集为 2 分钟),但我只对 4D 图像(sx、sy、通道、时间步长)进行了此操作,并且需要 z 切片的附加维度:
chunk_bits = 256 * 1000**2 # 256MB
frame_bits = depth_bits[dtype] * sx * sy * channels
chunk_frames = chunk_bits // frame_bits
a = numpy.zeros((sx, sy, channels, chunk_frames), dtype=dtype)
for i in range(0, layers):
img.seek(i)
temp = numpy.array(img.getdata(), dtype=dtype)
temp.resize(sx, sy, channels)
a[..., i % chunk_frames] = temp
if (i + 1) % chunk_frames == 0 or i == (layers - 1):
chunk = i // chunk_frames
dset[..., chunk * chunk_frames : i + 1] = a[..., : i % chunk_frames + 1