2010-02-26 3 views
5

Je crois que j'ai un problème de mémoire en utilisant des tableaux numpy. Le code suivant est en cours d'exécution pendant des heures:Problème de mémoire de tableau Numpy

new_data = npy.array([new_x, new_y1, new_y2, new_y3]) 
    private.data = npy.row_stack([private.data, new_data]) 

où new_x, new_y1, new_y2, new_y3 sont flotteurs.

Après environ 5 heures d'enregistrement de ces données toutes les secondes (plus de 72000 flotteurs), le programme ne répond plus. Ce qui se passe, à mon avis, c'est une sorte d'opération de réaffectation et de copie qui submerge le processus. Est-ce que quelqu'un sait si c'est ce qui se passe?

J'ai besoin d'un moyen d'enregistrer ces données sans rencontrer ce problème de ralentissement. Il n'y a aucun moyen de connaître même approximativement la taille de ce tableau au préalable. Il n'a pas nécessairement besoin d'utiliser un tableau numpy, mais il doit être quelque chose de similaire. Est-ce que quelqu'un sait d'une bonne méthode?

Répondre

2

Mise à jour: J'ai incorporé l'excellente suggestion d'indexation d'EOL dans la réponse.

Le problème est peut-être la façon dont row_stack développe la destination. Vous feriez mieux de gérer vous-même la réaffectation. Le code suivant attribue un grand tableau vide, remplit, et grandit comme il remplit une heure à la fois

numcols = 4 
growsize = 60*60 #60 samples/min * 60 min/hour 
numrows = 3*growsize #3 hours, to start with 
private.data = npy.zeros([numrows, numcols]) #alloc one big memory block 
rowctr = 0 
while (recording): 
    private.data[rowctr] = npy.array([new_x, new_y1, new_y2, new_y3]) 
    rowctr += 1 
    if (rowctr == numrows): #full, grow by another hour's worth of data 
     private.data = npy.row_stack([private.data, npy.zeros([growsize, numcols])]) 
     numrows += growsize 

Cela devrait garder le gestionnaire de mémoire de débattant trop. J'ai essayé cela par rapport à row_stack à chaque itération et il a couru quelques ordres de grandeur plus rapidement.

+0

Bonne idée. 'npy.empty' semble plus approprié que' npy.zeros' (et est probablement un peu plus rapide). – EOL

+0

C'est vraiment rapide. Encapsuler ceci dans une classe avec une méthode row_stack serait bien. – EOL

+1

Notez que 'private.data [rowctr] = ...' est beaucoup plus rapide que '[rowctr,:]'. – EOL

3

Utilisez les listes Python. Sérieusement, ils grandissent beaucoup plus efficacement. C'est pour cela qu'ils sont conçus. Ils sont remarquablement efficaces dans ce contexte.

Si vous avez besoin de créer un tableau à la fin (ou même occasionnellement au milieu de ce calcul), il sera beaucoup plus efficace de l'accumuler dans une liste en premier.