2010-02-26 29 views
5

Wydaje mi się, że mam problem z pamięcią za pomocą numpy array. Poniższy kod jest uruchamiany całymi godzinami:Problem z pamięcią tablicową Numpy

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

gdzie new_x, new_y1, new_y2, new_y3 są pływaki.

Po około 5 godzinach zapisu tych danych co sekundę (ponad 72000 ruchów) program przestaje reagować. To, co myślę, dzieje się, to jakaś operacja ponownego kopiowania i kopiowania, która bagatruje cały proces. Czy ktoś wie, czy tak się dzieje?

Potrzebuję sposobu na zapisanie tych danych bez napotykania problemu spowolnienia. Nie ma możliwości wcześniejszego poznania nawet przybliżonej wielkości tej tablicy. Nie musi koniecznie używać tablicy numpy, ale musi być coś podobnego. Czy ktoś wie o dobrej metodzie?

Odpowiedz

2

Aktualizacja: Włączyłem doskonałą sugestię indeksowania @ EOL do odpowiedzi.

Problem może być taki, że row_stack powiększa miejsce docelowe. Być może lepiej poradzisz sobie z samą realokacją. Poniższy kod przydziela dużą pustą tablicę, wypełnia je i rośnie go, gdyż wypełnia godzinę naraz

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 

ten powinien utrzymać menedżera pamięci od bicia wokół zbyt dużo. Próbowałem to w porównaniu do row_stack w każdej iteracji i działało o kilka rzędów wielkości szybciej.

+0

Dobry pomysł. 'npy.empty' wydaje się bardziej odpowiedni niż' npy.zeros' (i jest prawdopodobnie odrobinę szybszy). – EOL

+0

To jest naprawdę szybkie. Zamknięcie tego w klasie za pomocą metody row_stack byłoby miłe. – EOL

+1

Należy zauważyć, że 'private.data [rowctr] = ...' jest znacznie szybszy niż '[rowctr,:]'. – EOL

3

Użyj list Pythona. Poważnie, rosną znacznie efektywniej. Właśnie do tego są przeznaczone. Są niezwykle wydajne w tym ustawieniu.

Jeśli chcesz utworzyć z nich tablicę na końcu (lub nawet od czasu do czasu w trakcie tego obliczenia), będzie o wiele bardziej wydajnie gromadzić się na liście jako pierwsza.

Powiązane problemy