2

我有一个具有多个维度(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
4

1 回答 1

0

选项 1 是正确答案。但是,哪个维度变化最快会产生很大的不同:

〜15分钟:

for i in range(0, img_layers):
  img.seek(i)
  a = numpy.array(img.getdata(), dtype=dtype)
  a.resize(sx, sy, channels)
  z = i % sz
  frame = i // sz
  dset[..., z, frame] = a # Majority of time in this call

〜3分钟:

for i in range(0, img_layers):
  img.seek(i)
  a = numpy.array(img.getdata(), dtype=dtype) # Majority of time in this call
  a.resize(sx, sy, channels)
  z = i % sz
  frame = i // sz
  dset[frame, z, ...] = a

为了快速读取这些数据,变化最快的索引应该是 LAST,而不是第一个。

于 2013-11-19T13:44:40.713 回答