web-dev-qa-db-fra.com

Travailler avec des données volumineuses en python et numpy, pas assez de RAM, comment enregistrer des résultats partiels sur le disque?

J'essaie d'implémenter des algorithmes pour des données à 1000 dimensions avec 200k + points de données en python. Je veux utiliser numpy, scipy, sklearn, networkx et d'autres bibliothèques utiles. Je veux effectuer des opérations telles que la distance par paire entre tous les points et effectuer un regroupement sur tous les points. J'ai mis en œuvre des algorithmes de travail qui effectuent ce que je veux avec une complexité raisonnable, mais lorsque j'essaie de les adapter à toutes mes données, je manque de RAM. Bien sûr, je le fais, la création de la matrice pour des distances par paires sur 200k + données prend beaucoup de mémoire.

Voici le hic: j'aimerais vraiment le faire sur des ordinateurs pourris avec de faibles quantités de RAM.

Existe-t-il un moyen faisable pour moi de faire ce travail sans les contraintes de faible RAM. Que cela prenne beaucoup plus de temps n'est vraiment pas un problème, tant que les délais ne vont pas à l'infini!

J'aimerais pouvoir mettre mes algorithmes au travail, puis revenir une heure ou cinq plus tard et ne pas le bloquer car il n'a plus de mémoire vive! Je voudrais implémenter cela en python, et pouvoir utiliser les bibliothèques numpy, scipy, sklearn et networkx. Je voudrais pouvoir calculer la distance par paire à tous mes points, etc.

Est-ce faisable? Et comment pourrais-je m'y prendre, sur quoi puis-je commencer à lire?

Cordialement // Envoûteur

42
Ekgren

En utilisant numpy.memmap vous créez des tableaux directement mappés dans un fichier:

import numpy
a = numpy.memmap('test.mymemmap', dtype='float32', mode='w+', shape=(200000,1000))
# here you will see a 762MB file created in your working directory    

Vous pouvez le traiter comme un tableau conventionnel: a + = 1000.

Il est même possible d'attribuer plus de tableaux au même fichier, en le contrôlant à partir de sources mutuelles si nécessaire. Mais j'ai vécu des choses délicates ici. Pour ouvrir le tableau complet, vous devez d'abord "fermer" le précédent, en utilisant del:

del a    
b = numpy.memmap('test.mymemmap', dtype='float32', mode='r+', shape=(200000,1000))

Mais l'ouverture d'une partie seulement du tableau permet de réaliser le contrôle simultané:

b = numpy.memmap('test.mymemmap', dtype='float32', mode='r+', shape=(2,1000))
b[1,5] = 123456.
print a[1,5]
#123456.0

Génial! a a été modifié avec b. Et les modifications sont déjà écrites sur le disque.

L'autre élément important qui mérite d'être commenté est le offset. Supposons que vous souhaitiez prendre non pas les 2 premières lignes de b, mais les lignes 150000 et 150001.

b = numpy.memmap('test.mymemmap', dtype='float32', mode='r+', shape=(2,1000),
                 offset=150000*1000*32/8)
b[1,2] = 999999.
print a[150001,2]
#999999.0

Vous pouvez désormais accéder et mettre à jour n'importe quelle partie de la baie en opérations simultanées. Notez la taille d'octet dans le calcul du décalage. Ainsi, pour un "float64", cet exemple serait 150000 * 1000 * 64/8.

Autres références:

57