2012-02-12 15 views
8

Considerare i seguenti vettori (essenzialmente 2x1 matrici):prodotto trasversale di un vettore in NumPy

a = sc.array([[1], [2], [3]]) 
>>> a 
[[1] 
[2] 
[3]] 

b = sc.array([[4], [5], [6]]) 
>>> b 
[[4] 
[5] 
[6]] 

Il prodotto incrociato di questi vettori può essere calcolata utilizzando numpy.cross(). Perché questo non funziona:

import numpy as np 

np.cross(a, b) 
ValueError: incompatible dimensions for cross product 
(dimension must be 2 or 3) 

ma questo fa ?:

np.cross(a.T, b.T) 
[[-3 6 -3]] 

risposta

14

Per calcolare il prodotto incrociato utilizzando numpy.cross, la dimensione (lunghezza) della dimensione di matrice che definisce i due vettori devono o da due o tre. Per citare la documentazione:

Se a e b sono array di vettori, i vettori sono definiti dal ultimo asse di a e b per impostazione predefinita, e questi assi possono avere dimensioni 2 o 3.

Si noti che l'ultimo asse è il valore predefinito. Nel tuo esempio:

In [17]: a = np.array([[1], [2], [3]]) 

In [18]: b = np.array([[4], [5], [6]]) 

In [19]: print a.shape,b.shape 
(3, 1) (3, 1) 

l'ultimo asse è solo di lunghezza 1, quindi il prodotto incrociato non è definito. Tuttavia, se si utilizza la trasposizione, la lunghezza lungo l'ultimo asse è 3, quindi è valida. Si potrebbe anche fare:

In [20]: np.cross(a,b,axis=0) 
Out[20]: 
array([[-3], 
     [ 6], 
     [-3]]) 

che racconta cross che i vettori sono definite lungo il primo asse, piuttosto che l'ultimo asse.

+0

Interessante, grazie. È possibile modificare l'asse predefinito su 0? – Ingo

+1

@thomas: Non che io sappia. Ma è davvero un compito così arduo seguire le convenzioni della biblioteca quando si definiscono i propri vettori o definire esplicitamente il loro ordine alla chiamata? – talonmies

+0

No, non lo è, ma sto scrivendo il codice per alcuni studenti e per vexperience li confonde se per esempio i vettori sono tutti vettori di riga quando sono usati per i vettori di colonne. – Ingo

1

È necessario creare un e b come questo:

a = sc.array([1, 2, 3]) 
b = sc.array([4, 5, 6]) 

in modo che abbiano dimensione = 3.

3

In NumPy usiamo spesso gli array 1D per rappresentare i vettori, e lo trattiamo come sia un vettore riga o di un vettore colonna a seconda del contesto, per esempio:

In [13]: a = np.array([1, 2, 3]) 

In [15]: b = np.array([4, 5, 6]) 

In [16]: np.cross(a, b) 
Out[16]: array([-3, 6, -3]) 

In [17]: np.dot(a, b) 
Out[17]: 32 

è possibile memorizzare vettori come array 2D, questo è molto utile quando si dispone di una collezione di vettori che si desidera trattare in modo simile Per esempio se voglio incrociare 4 vettori in a con 4 vettori in b. Per impostazione predefinita numpy presuppone che i vettori siano lungo le ultime dimensioni, ma è possibile utilizzare gli argomenti axisa e axisb per specificare esplicitamente che i vettori si trovano lungo la prima dimensione.

In [26]: a = np.random.random((3, 4)) 

In [27]: b = np.random.random((3, 4)) 

In [28]: np.cross(a, b, axisa=0, axisb=0) 
Out[28]: 
array([[-0.34780508, 0.54583745, -0.25644455], 
     [ 0.03892861, 0.18446659, -0.36877085], 
     [ 0.36736545, 0.13549752, -0.32647531], 
     [-0.46253185, 0.56148668, -0.10056834]]) 
+2

Bago solleva il punto qui. Numpy non è MATLAB, puoi (e dovresti) dimenticare colonne e righe perché gli array sono un concetto computazionale e non ce l'hanno. Le matrici lo fanno. – astrojuanlu

Problemi correlati