Entrada y salida de matrices numpy a h5py

100

Tengo un código Python cuya salida es una ingrese la descripción de la imagen aquímatriz de tamaño, cuyas entradas son todas del tipo float. Si lo guardo con la extensión, .datel tamaño del archivo es del orden de 500 MB. Leí que el uso h5pyreduce considerablemente el tamaño del archivo. Entonces, digamos que tengo la matriz numpy 2D nombrada A. ¿Cómo lo guardo en un archivo h5py? Además, ¿cómo leo el mismo archivo y lo pongo como una matriz numérica en un código diferente, ya que necesito hacer manipulaciones con la matriz?

lovepeed
fuente
4
¿Cómo lo guardas con la .datextensión?
jorgeca
@jorgeca: por eso acabo de hacernp.savetxt("output.dat",A,'%10.8e')
lovespeed
3
Gracias (la extensión por sí sola no significa mucho, podría almacenarse como binario, ascii ...). A menos que necesite las funciones adicionales de hdf5, solo usaría lo np.save('output.dat', A)que lo guardará en un formato binario (mucho más rápido, se usa mucho menos espacio).
jorgeca
@jorgeca, pero ¿otro script de Python podrá leerlo como una matriz 2D cuando lo llame comoA = np.loadtxt('output.dat',unpack=True)
lovespeed
2
entonces, h5py¿no crea archivos más pequeños de lo que lo np.saveharían? es h5pymás rápido que np.savepara matrices del tamaño dado en la pregunta?
dbliss

Respuestas:

131

h5py proporciona un modelo de conjuntos de datos y grupos . El primero es básicamente matrices y el segundo se puede considerar como directorios. Cada uno tiene un nombre. Debería consultar la documentación de la API y los ejemplos:

http://docs.h5py.org/en/latest/quick.html

Un ejemplo simple en el que está creando todos los datos por adelantado y solo desea guardarlos en un archivo hdf5 se vería así:

In [1]: import numpy as np
In [2]: import h5py
In [3]: a = np.random.random(size=(100,20))
In [4]: h5f = h5py.File('data.h5', 'w')
In [5]: h5f.create_dataset('dataset_1', data=a)
Out[5]: <HDF5 dataset "dataset_1": shape (100, 20), type "<f8">

In [6]: h5f.close()

Luego puede volver a cargar esos datos usando: '

In [10]: h5f = h5py.File('data.h5','r')
In [11]: b = h5f['dataset_1'][:]
In [12]: h5f.close()

In [13]: np.allclose(a,b)
Out[13]: True

Definitivamente echa un vistazo a los documentos:

http://docs.h5py.org

Escribir en un archivo hdf5 depende de h5py o pytables (cada uno tiene una API de Python diferente que se encuentra en la parte superior de la especificación del archivo hdf5). También debe echar un vistazo a otros formatos binarios simples proporcionados por numpy de forma nativa, como np.save, np.savezetc.

http://docs.scipy.org/doc/numpy/reference/routines.io.html

JoshAdel
fuente
Por cierto. Si no conoce el nombre del conjunto de datos de antemano mientras lee, debe analizar el archivo hdf de manera similar a aquí .
Trilarion
@JoshAdel si quiero agregar una columna al conjunto de datos. mi conjunto de datos es un np.array multidimensional indexado como [img_id, filas, columnas, canales]. y lo he guardado usando el método descrito en su respuesta. Accedo a todos los puntos en el conjunto de datos usando h5f ['dataset_1'] [img_id]. lo que quiero es una forma de agregar otra columna que diga 'mycolumn' ... correspondiente a cada img_id en el conjunto de datos. ¿Cómo debo agregar otra columna a esto para poder hacer h5f ['mycolumn'] [img_id]?
iratzhash
Si escribo matrices como esta, entonces no puedo verlas con HDFView 2.11. Puedo abrir el archivo, puedo ver que el conjunto de datos data.h5existe, pero no puedo verlo con HDFView. Puedo leer el contenido con h5py, pero no inspeccionarlo con HDFView. ¿Alguna idea de por qué?
Martin Thoma
104

Una forma más limpia de manejar archivos abiertos / cerrados y evitar pérdidas de memoria:

Deberes:

import numpy as np
import h5py

data_to_write = np.random.random(size=(100,20)) # or some such

Escribir:

with h5py.File('name-of-file.h5', 'w') as hf:
    hf.create_dataset("name-of-dataset",  data=data_to_write)

Leer:

with h5py.File('name-of-file.h5', 'r') as hf:
    data = hf['name-of-dataset'][:]
Lavi Avigdor
fuente
2
¿No es necesario cerrar el archivo?
ricoamor
22
@DrDeSancho no, la declaración con
Leonid
1
especialmente útil cuando se ejecuta en modo interactivo (porque de lo contrario uno corre el riesgo de obtener una excepción de h5py sobre un archivo ya abierto cuando se vuelve a ejecutar el mismo código sin cerrar correctamente en el primer intento)
Andre Holzner
La withcaracterística de Python se conoce como administrador de contexto. Se asegurará de que el archivo se cierre después de que se haya utilizado. Más información está disponible en la documentación oficial: docs.python.org/3/library/contextlib.html
Mark