2013-07-03 17 views
7

Załóżmy, że mamy dwie matryce: A i B i pozostawmy matrycę C (mnożenie macierzy nie elementycznie). Chcemy uzyskać tylko przekątne wpisy C, które można wykonać przez np.diagonal(C). Powoduje to jednak niepotrzebne obciążenie czasowe, ponieważ mnożymy A z B, mimo że potrzebujemy tylko multiplikacji każdego wiersza w A z kolumną B, która ma ten sam "identyfikator", czyli wiersz 1 z A z kolumną 1 z B, wiersz 2 z A z kolumną 2 z B i tak dalej: multiplikacje, które tworzą przekątną C. Czy istnieje sposób, aby skutecznie osiągnąć to za pomocą Numpy? Chcę uniknąć używania pętli do kontrolowania, który wiersz jest pomnożony przez kolumnę, zamiast tego życzę sobie wbudowanej metody numpy, która wykonuje tego rodzaju operacje w celu optymalizacji wydajności.(Python) Jak uzyskać przekątną (A * B) bez wykonywania A * B?

góry dzięki ..

+0

Uwaga dla każdego, kto na to patrzy: 'A * B' w NumPy to mnożenie elementarne, a nie mnożenie macierzy (które jest' a.dot (b) '). – Blair

+0

to 'A' i' B' typu 'ndarray' lub' matrix'? – Bitwise

+0

@Blair, tak jest w przypadku, gdy 'A' i' B' są 'numpy.array'. Jeśli są to "numpy.matrix", możesz użyć 'A * B' –

Odpowiedz

15

mogę używać einsum tutaj:

>>> a = np.random.randint(0, 10, (3,3)) 
>>> b = np.random.randint(0, 10, (3,3)) 
>>> a 
array([[9, 2, 8], 
     [5, 4, 0], 
     [8, 0, 6]]) 
>>> b 
array([[5, 5, 0], 
     [3, 5, 5], 
     [9, 4, 3]]) 
>>> a.dot(b) 
array([[123, 87, 34], 
     [ 37, 45, 20], 
     [ 94, 64, 18]]) 
>>> np.diagonal(a.dot(b)) 
array([123, 45, 18]) 
>>> np.einsum('ij,ji->i', a,b) 
array([123, 45, 18]) 

Dla większych tablic, to będzie znacznie szybciej niż robi mnożenia bezpośrednio:

>>> a = np.random.randint(0, 10, (1000,1000)) 
>>> b = np.random.randint(0, 10, (1000,1000)) 
>>> %timeit np.diagonal(a.dot(b)) 
1 loops, best of 3: 7.04 s per loop 
>>> %timeit np.einsum('ij,ji->i', a, b) 
100 loops, best of 3: 7.49 ms per loop 

[Uwaga: początkowo zrobiłem ten elementwise wersja, ii,ii->i, zamiast mnożenia macierzy. Te same sztuczki einsum działają.]

+1

Świetne rozwiązanie i użyteczny test porównawczy! Dziękuję Ci! – Curious

-1
def diag(A,B): 
    diags = [] 
    for x in range(len(A)): 
     diags.append(A[x][x] * B[x][x]) 
    return diags 

Wierzę, że powyższy kod jest to, że szukasz.

+4

Nie jest tak, jak [mnożenie macierzy] (http://en.wikipedia.org/wiki/Matrix_multiplication#Matrix_product_.28two_matrices.29) działa –

+0

Przepraszam. Nie wiedziałem, czy chodziło Ci o produkt skalarny czy produkt matrycowy. – BenjaminCohen

Powiązane problemy