2014-04-08 13 views
5

Sto lavorando con numpy in python per calcolare una moltiplicazione vettoriale. Ho un vettore x di dimensioni n x 1 e voglio calcolare x * x_transpose. Questo mi dà problemi perché x.T o x.transpose() non ha effetto su un vettore a 1 dimensione (numpy rappresenta i vettori verticale e orizzontale allo stesso modo).punto prodotto di due vettori 1D in numpy

Ma come si calcola una moltiplicazione vettoriale (n x 1) x (1 x n) in numpy?

numpy.dot (x, x.T) fornisce una matrice scalare, non una 2D come voglio.

+0

Esempio 'x' per favore? – cdhagmann

+0

@ ᴋᴇʏsᴇʀ dà una matrice – cdhagmann

+0

@cdhagmann Y. Ho notato che le dimensioni – keyser

risposta

11

Si sono essenzialmente Computing un Outer Product.

È possibile utilizzare np.outer.

In [15]: a=[1,2,3] 

In [16]: np.outer(a,a) 
Out[16]: 
array([[1, 2, 3], 
     [2, 4, 6], 
     [3, 6, 9]]) 
+3

Accetterò questo più tardi quando il periodo di 10min è finito – Vjeetje

1

Se si desidera un prodotto interno quindi utilizzare numpy.dot(x,x) per il prodotto esterno utilizzare numpy.outer(x,x)

5

Mentre np.outer è il modo più semplice per fare questo, avevo pensato che avevo appena parlato come si potrebbe manipolare la (N,) a forma di array per fare questo:

In [17]: a = np.arange(4) 
In [18]: np.dot(a[:,None], a[None,:]) 
Out[18]: 
array([[0, 0, 0, 0], 
     [0, 1, 2, 3], 
     [0, 2, 4, 6], 
     [0, 3, 6, 9]]) 

In [19]: np.outer(a,a) 
Out[19]: 
array([[0, 0, 0, 0], 
     [0, 1, 2, 3], 
     [0, 2, 4, 6], 
     [0, 3, 6, 9]]) 

Dove si potrebbe in alternativa sostituire None con np.newaxis.

Un altro modo più esotico di fare questo è con np.einsum:

In [20]: np.einsum('i,j', a, a) 
Out[20]: 
array([[0, 0, 0, 0], 
     [0, 1, 2, 3], 
     [0, 2, 4, 6], 
     [0, 3, 6, 9]]) 

E solo per divertimento, alcuni tempi, che sono probabilmente andando a variare in base all'hardware e NumPy versione/compilazione:

Piccolo -ish vettore

In [36]: a = np.arange(5, dtype=np.float64) 

In [37]: %timeit np.outer(a,a) 
100000 loops, best of 3: 17.7 µs per loop 

In [38]: %timeit np.dot(a[:,None],a[None,:]) 
100000 loops, best of 3: 11 µs per loop 

In [39]: %timeit np.einsum('i,j', a, a) 
1 loops, best of 3: 11.9 µs per loop 

In [40]: %timeit a[:, None] * a 
100000 loops, best of 3: 9.68 µs per loop 

E qualcosa di un po 'più grande

In [42]: a = np.arange(500, dtype=np.float64) 

In [43]: %timeit np.outer(a,a) 
1000 loops, best of 3: 605 µs per loop 

In [44]: %timeit np.dot(a[:,None],a[None,:]) 
1000 loops, best of 3: 1.29 ms per loop 

In [45]: %timeit np.einsum('i,j', a, a) 
1000 loops, best of 3: 359 µs per loop 

In [46]: %timeit a[:, None] * a 
1000 loops, best of 3: 597 µs per loop 
+3

Non dimenticare 'a [:, None] * a'! – Daniel

+0

@Ophion ringrazia per aver notato la soluzione generale di trasmissione. – JoshAdel

0

Un'altra alternativa è quella di utente numpy.matrix

>>> a = np.matrix([1,2,3]) 
>>> a 
matrix([[1, 2, 3]]) 
>>> a.T * a 
matrix([[1, 2, 3], 
     [2, 4, 6], 
     [3, 6, 9]]) 

Generalmente uso di numpy.arrays è preferito. Tuttavia, l'utilizzo di numpy.matrices può essere più leggibile per le espressioni lunghe.

0

Un'altra alternativa è definire il vettore riga/colonna con 2 dimensioni, ad es.

a = np.array([1, 2, 3], ndmin=2) 
np.dot(a.T, a) 

array([[1, 2, 3], 
    [2, 4, 6], 
    [3, 6, 9]]) 
Problemi correlati