Python 如何从一维源填充HDF5中的n维数组?

Python 如何从一维源填充HDF5中的n维数组?,python,numpy,hdf5,h5py,Python,Numpy,Hdf5,H5py,我有一个多维数组(x、y、通道、z、时间步长)。但是,原始数据以单个堆栈(x、y、通道)的形式存储在TIFF图像中,具有z*时间步长帧 最后,Pillow的Image.getdata()函数返回一个1D数组状的对象,该对象需要重新整形 如果数据集太大,无法放入内存,那么将其读入HDF5的最佳方法是什么?是否可以在写入HDF5后重塑阵列,或以自动填充阵列的方式写入1D数据(即以x变化最快、y次之快等写入)更新:类似的方式将是理想的 以下是我迄今为止所尝试的(img是PIL.Image,dset是h

我有一个多维数组(x、y、通道、z、时间步长)。但是,原始数据以单个堆栈(x、y、通道)的形式存储在TIFF图像中,具有z*时间步长帧

最后,Pillow的Image.getdata()函数返回一个1D数组状的对象,该对象需要重新整形

如果数据集太大,无法放入内存,那么将其读入HDF5的最佳方法是什么?是否可以在写入HDF5后重塑阵列,或以自动填充阵列的方式写入1D数据(即以x变化最快、y次之快等写入)更新:类似的方式将是理想的

以下是我迄今为止所尝试的(img是PIL.Image,dset是h5py数据集):

1) 阅读单个帧。此方法速度太慢,因为在1000帧中300 MB需要约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

选项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
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
~3分钟:

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
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
要快速读取这些数据,变化最快的索引应该是最后一个,而不是第一个