2013-06-07 8 views
6

mam tablicy A, który ma kształt (M, N) teraz dalszy jak przeprowadzić operacjęMultipying i dodając wewnątrz na zbyt dużej tablicy

R = (A[:,newaxis,:] * A[newaxis,:,:]).sum(2)

które powinny otrzymując produkt (MxM). Problem polega na tym, że tablica jest dość duża i pojawia się błąd pamięci, ponieważ tablica MxMxN nie pasuje do pamięci.

jaka byłaby najlepsza strategia, aby to zrobić? C? mapa()? lub czy jest jeszcze specjalna funkcja?

dziękuję Dawida

+0

Czy "A" jest tablicą MxN? Chyba "A [:, newaxis,:]" jest tablicą MxN. Nawet wtedy: "A [:, newaxis ,:] * A [newaxis,:,:]" powinno dać dwuwymiarową tablicę, więc nie rozumiem 'sum (2)', ponieważ nie ma trzeciej osi (lub newaxis to plaster, a nie pojedynczy numer). Coś tu brakuje. – Evert

+0

W zależności od wymaganej precyzji, można próbować użyć innego typu dla wartości w tablicy. Np. 'Numpy.float32' lub' numpy.int16'. To może zmniejszyć o połowę zapotrzebowanie na pamięć. – Evert

+0

@Evert A [:, np.newaxis,:]. Shape == (M, 1, N) i (A [:, np.newaxis ,:] * A [np.newaxis,:,:]). Shape == (M, M, N) – JoshAdel

Odpowiedz

7

Nie jestem pewien, jak duże tablice są, ale po to równoważne:

R = np.einsum('ij,kj',A,A) 

i może być trochę szybciej i jest znacznie mniej intensywnie wykorzystujących pamięć:

In [7]: A = np.random.random(size=(500,400)) 

In [8]: %timeit R = (A[:,np.newaxis,:] * A[np.newaxis,:,:]).sum(2) 
1 loops, best of 3: 1.21 s per loop 

In [9]: %timeit R = np.einsum('ij,kj',A,A) 
10 loops, best of 3: 54 ms per loop 

Gdybym zwiększyć rozmiar A do (500,4000), np.einsum pługów przez calculatio n w ciągu około 2 sekund, podczas gdy pierwotna formuła zmiażdży moją maszynę do zatrzymania ze względu na rozmiar tymczasowej macierzy, którą ma utworzyć.

Aktualizacja:

Jak @Jaime zauważył w komentarzach, np.dot(A,A.T) jest równoważny sformułowanie problemu, a może być nawet szybciej niż roztwór np.einsum. Przyznaję mu pełną wagę za wskazanie tego, ale na wypadek, gdyby nie napisał tego jako formalnego rozwiązania, chciałem wyciągnąć to z głównej odpowiedzi.

+7

+1 Ale obliczenia OP są również równoważne z 'np.dot (A, AT)', aw moim systemie dla tablicy w kształcie '(500, 400) 'jest około 10 razy szybszy niż' np.einsum' , która jest już 6 razy szybsza niż metoda OP. – Jaime

+0

@Jaime dobry połów. Napisz to jako odpowiedź, a ja ją przegłosuję. fwiw, 'np.dot' jest tylko o 2,5 szybszy niż' np.einsum' na moim komputerze dla (500400). Dla (500,4000) chociaż 'np.dot' jest około 10 razy szybsze. – JoshAdel

+0

Jestem dziwką reputacyjną, po prostu nie aż tak wiele; ;-) Zapraszam do zamieszczania taktowania 'np.dot' jeśli chcesz, myślę, że będzie czystsza z jedną odpowiedzią. – Jaime

Powiązane problemy