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.
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
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
@Evert A [:, np.newaxis,:]. Shape == (M, 1, N) i (A [:, np.newaxis ,:] * A [np.newaxis,:,:]). Shape == (M, M, N) – JoshAdel