Estoy buscando una forma rápida de preservar grandes matrices numpy. Quiero guardarlos en el disco en formato binario y luego volver a leerlos en la memoria con relativa rapidez. cPickle no es lo suficientemente rápido, desafortunadamente.
Encontré numpy.savez y numpy.load . Pero lo extraño es que numpy.load carga un archivo npy en "memory-map". Eso significa que la manipulación regular de matrices es muy lenta. Por ejemplo, algo como esto sería muy lento:
#!/usr/bin/python
import numpy as np;
import time;
from tempfile import TemporaryFile
n = 10000000;
a = np.arange(n)
b = np.arange(n) * 10
c = np.arange(n) * -0.5
file = TemporaryFile()
np.savez(file,a = a, b = b, c = c);
file.seek(0)
t = time.time()
z = np.load(file)
print "loading time = ", time.time() - t
t = time.time()
aa = z['a']
bb = z['b']
cc = z['c']
print "assigning time = ", time.time() - t;
más precisamente, la primera línea será realmente rápida, pero las líneas restantes que asignan las matrices obj
son ridículamente lentas:
loading time = 0.000220775604248
assining time = 2.72940087318
¿Hay alguna forma mejor de preservar matrices numpy? Idealmente, quiero poder almacenar múltiples matrices en un archivo.
np.load
debería mmap del archivo.numpy.savez
), el valor predeterminado es "cargar lentamente" los arreglos. No los está mapeando, pero no los carga hasta que elNpzFile
objeto está indexado. (Por lo tanto, el retraso al que se refiere el OP.) La documentación paraload
omite esto, y por lo tanto es un poco engañoso ...Respuestas:
Soy un gran fan de hdf5 para almacenar grandes matrices numpy. Hay dos opciones para tratar con hdf5 en python:
http://www.pytables.org/
http://www.h5py.org/
Ambos están diseñados para funcionar con matrices numpy de manera eficiente.
fuente
He comparado el rendimiento (espacio y tiempo) de varias formas de almacenar matrices numpy. Pocos admiten múltiples matrices por archivo, pero quizás sea útil de todos modos.
Los archivos Npy y binarios son realmente rápidos y pequeños para datos densos. Si los datos son escasos o muy estructurados, es posible que desee usar npz con compresión, lo que ahorrará mucho espacio pero costará algo de tiempo de carga.
Si la portabilidad es un problema, binary es mejor que npy. Si la legibilidad humana es importante, entonces tendrá que sacrificar mucho rendimiento, pero se puede lograr bastante bien usando csv (que también es muy portátil, por supuesto).
Más detalles y el código están disponibles en el repositorio de github .
fuente
binary
es mejor quenpy
por portabilidad? ¿Esto también se aplicanpz
?Ahora hay un clon basado en HDF5 de
pickle
calledhickle
!https://github.com/telegraphic/hickle
EDITAR:
También existe la posibilidad de "encurtir" directamente en un archivo comprimido haciendo:
Apéndice
fuente
savez () guarda los datos en un archivo zip. Puede llevar algún tiempo comprimir y descomprimir el archivo. Puede usar la función save () & load ():
Para guardar varias matrices en un archivo, solo necesita abrir el archivo primero y luego guardar o cargar las matrices en secuencia.
fuente
Otra posibilidad para almacenar matrices numpy de manera eficiente es Bloscpack :
y la salida de mi computadora portátil (una MacBook Air relativamente antigua con un procesador Core2):
eso significa que se puede almacenar muy rápido, es decir, el cuello de botella suele ser el disco. Sin embargo, como las relaciones de compresión son bastante buenas aquí, la velocidad efectiva se multiplica por las relaciones de compresión. Estos son los tamaños de estas matrices de 76 MB:
Tenga en cuenta que el uso del compresor Blosc es fundamental para lograrlo. El mismo script pero usando 'clevel' = 0 (es decir, desactivando la compresión):
está claramente atascado por el rendimiento del disco.
fuente
El tiempo de búsqueda es lento porque cuando lo usa
mmap
no carga el contenido de la matriz en la memoria cuando invoca elload
método. Los datos se cargan de forma diferida cuando se necesitan datos particulares. Y esto sucede en la búsqueda en su caso. Pero la segunda búsqueda no será tan lenta.Esta es una buena característica de
mmap
cuando tiene una gran matriz, no tiene que cargar datos completos en la memoria.Para resolver su puede usar joblib , puede volcar cualquier objeto que desee usando
joblib.dump
incluso dos o másnumpy arrays
, vea el ejemplofuente