Je recherche un moyen rapide de conserver de grands tableaux numpy. Je veux les enregistrer sur le disque au format binaire, puis les relire en mémoire relativement rapidement. cPickle n'est malheureusement pas assez rapide.
J'ai trouvé numpy.savez et numpy.load . Mais la chose étrange est que numpy.load charge un fichier npy dans "memory-map". Cela signifie que la manipulation régulière des tableaux est vraiment lente. Par exemple, quelque chose comme ça serait vraiment lent:
#!/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;
plus précisément, la première ligne sera vraiment rapide, mais les lignes restantes qui assignent les tableaux obj
sont ridiculement lentes:
loading time = 0.000220775604248
assining time = 2.72940087318
Existe-t-il un meilleur moyen de préserver les tableaux numpy? Idéalement, je souhaite pouvoir stocker plusieurs tableaux dans un seul fichier.
np.load
doit pas mmapper le fichier.numpy.savez
), la valeur par défaut est de "charger paresseusement" les tableaux. Il ne les mappe pas, mais il ne les charge pas tant que l'NpzFile
objet n'est pas indexé. (Ainsi, le délai auquel l'OP fait référence.) La documentation pourload
ignorer cela, et est donc un peu trompeuse ...Réponses:
Je suis un grand fan de hdf5 pour stocker de grands tableaux numpy. Il existe deux options pour gérer hdf5 en python:
http://www.pytables.org/
http://www.h5py.org/
Les deux sont conçus pour fonctionner efficacement avec des tableaux numpy.
la source
J'ai comparé les performances (espace et temps) pour un certain nombre de façons de stocker des tableaux numpy. Peu d'entre eux prennent en charge plusieurs tableaux par fichier, mais c'est peut-être utile quand même.
Les fichiers Npy et binaires sont à la fois très rapides et petits pour les données denses. Si les données sont rares ou très structurées, vous pouvez utiliser npz avec compression, ce qui économisera beaucoup d'espace mais coûtera du temps de chargement.
Si la portabilité est un problème, le binaire est meilleur que npy. Si la lisibilité humaine est importante, vous devrez sacrifier beaucoup de performances, mais cela peut être assez bien réalisé en utilisant csv (qui est également très portable bien sûr).
Plus de détails et le code sont disponibles dans le dépôt github .
la source
binary
c'est mieux quenpy
pour la portabilité? Cela vaut-il également pournpz
?Il existe maintenant un clone basé sur HDF5 de
pickle
calledhickle
!https://github.com/telegraphic/hickle
ÉDITER:
Il y a aussi la possibilité de "pickle" directement dans une archive compressée en faisant:
appendice
la source
savez () enregistrer les données dans un fichier zip, cela peut prendre un certain temps pour compresser et décompresser le fichier. Vous pouvez utiliser la fonction save () & load ():
Pour enregistrer plusieurs tableaux dans un fichier, il vous suffit d'ouvrir d'abord le fichier, puis d'enregistrer ou de charger les tableaux dans l'ordre.
la source
Une autre possibilité de stocker efficacement des tableaux numpy est Bloscpack :
et la sortie de mon ordinateur portable (un MacBook Air relativement ancien avec un processeur Core2):
cela signifie qu'il peut stocker très rapidement, c'est-à-dire que le goulot d'étranglement est généralement le disque. Cependant, comme les taux de compression sont assez bons ici, la vitesse effective est multipliée par les taux de compression. Voici les tailles de ces baies de 76 Mo:
Veuillez noter que l'utilisation du compresseur Blosc est fondamentale pour y parvenir. Le même script mais en utilisant 'clevel' = 0 (c'est-à-dire en désactivant la compression):
est clairement goulot d'étranglement par les performances du disque.
la source
Le temps de recherche est lent car lorsque vous utilisez
mmap
pour ne charge pas le contenu du tableau en mémoire lorsque vous appelez laload
méthode. Les données sont chargées paresseusement lorsque des données particulières sont nécessaires. Et cela se produit lors de la recherche dans votre cas. Mais la deuxième recherche ne sera pas si lente.C'est une fonctionnalité intéressante
mmap
lorsque vous avez un grand tableau, vous n'avez pas à charger des données entières en mémoire.Pour résoudre votre problème d'utilisation de joblib, vous pouvez vider n'importe quel objet de votre choix en utilisant
joblib.dump
même deux ou plusnumpy arrays
, voir l'exemplela source