Pregunta

Tengo una matriz con múltiples dimensiones (x, y, canales, z, pasos de tiempo). Sin embargo, los datos en bruto se almacenan en una imagen TIFF como una sola pila de (x, y, canales), con marcos Z * pasos de tiempo.

Finalmente, la función Image.GetData () devuelve un objeto similar a una matriz 1D que necesita ser remodelada.

¿Cuál es la mejor manera de leer esto en HDF5 si el conjunto de datos es demasiado grande para caber en la memoria? ¿Es posible remodelar la matriz una vez que se haya escrito en HDF5, o para escribir datos 1D de una manera que complete automáticamente una matriz (es decir, escribe con x variable más rápido, y segundo, etc.) actualización : algo como numpy.ndarray.flat < / a> sería ideal.

Aquí está lo que he intentado hasta ahora (IMG es Pil.Image, Dset es un conjunto de datos H5PY):

1) Lectura de marcos individuales. Este método es demasiado lento, ya que tarda ~ 20min por 300 MB en 1000 cuadros. La mayor parte del tiempo se gasta en el DST []= una llamada.

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) incompleto: leyendo en trozos. Esto es mucho más rápido (2 minutos para el mismo conjunto de datos), pero solo tengo esto trabajando para una imagen 4D (SX, SY, canales, pasos de tiempo) y necesitan una dimensión adicional para Z-Slices:

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

¿Fue útil?

Solución

La opción 1 fue la respuesta correcta.Sin embargo, hace una gran diferencia en la que la dimensión varía más rápido:

~ 15 minutos:

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 minutos:

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

Para leer estos datos rápidamente, el índice variable más rápido debe ser el último, no primero.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top