2016-06-07 15 views
3

Ich habe ein Python-Programm gesehen und ausgeführt, wo eine Matrix in einen Spaltenvektor unter Verwendung a[:,j] geschnitten und in eine Funktion übergeben wurde. Der Spaltenvektor hat die Dimensionen 40000x1. Beim Verfolgen der Ausgabe druckte ich die Dimensionen a in der Funktion und druckte (40000,). In der Funktion wird diese Matrix mit einer Matrix b der Dimensionen 1x40000 multipliziert. Ich habe die Abmessungen des Ergebnisses ausgedruckt und es steht auch das Ergebnis 1x40000. Wie ist das möglich? Ich habe gelesen, dass a wird ein Spaltenvektor (natürlich), aber wie kann das Produkt eine 1x40000 Matrix erzeugen? Es erfüllt nicht die Matrixmultiplikationsregel. Ich verwende numpy.Python-Matrix dargestellt als (40000,)

EDIT:

Code:

def update_state(xk, sk, wx, wRec): 
    print("Sizes:") 
    print(xk.shape) 
    print(wx.shape) 
    print((xk*wx).shape) 
    print((xk * wx + sk * wRec).shape) 
    return xk * wx + sk * wRec 

def forward_states(X, wx, wRec): 
    S = np.zeros((X.shape[0], X.shape[1]+1)) 
    for k in range(0, X.shape[1]): 
     S[:,k+1] = update_state(X[:,k], S[:,k], wx, wRec) 
    return S 

Ausgang:

Sizes: 
(40000,) 
(1, 40000) 
(1, 40000) 
(1, 40000) 
+1

Wenn Sie ein paar Zeilen Beispielcode zur Verfügung stellen, wäre das großartig. Zu wissen, auf welche Bibliothek und Funktion Sie sich beziehen, würde einen Unterschied machen, da sie alle etwas unterschiedliche Arten haben, mit diesen Dingen umzugehen. –

Antwort

1

Ich gehe davon aus, dass Sie die numpy Paket beziehen. Es gibt andere Array-Pakete für Python, aber das scheint die beliebteste zu sein.

numpy beschäftigt sich mit mehrdimensionalen Arrays, nicht Matrizen. Es gibt einen großen Unterschied darin, dass ein 1D-Array von N Elementen entweder als eine Nx1- oder eine 1xN-Matrix interpretiert werden kann, je nachdem, wie Sie es interpretieren möchten.

Eine andere Sache bewusst zu sein, dass die Funktion numpy.multiply, auch bekannt als der * Betreiber nicht das gleiche wie numpy.dot, a.k.a der @ Operator ist. Die Operationen, die * betreffen, sehen Sie in Ihrem Code Element-für-Element-Multiplikation, nicht Matrix-Multiplikation, wie Sie zu denken scheinen.

numpy bietet eine Reihe verschiedener Mechanismen zum Mapping von Elementen von Arrays mit kompatiblen Dimensionen zueinander. Die gebräuchlichste Methode, die in Ihrem Beispiel verwendet wird, lautet broadcasting.

Lassen Sie uns die Informationen in der Verknüpfung kx * wx in Ihrem Code anwenden. Ich werde eine vereinfachte Version von kx und wx verwenden, die es leichter zu veranschaulichen die Frage auf der Hand machen:

>>> kx = np.arange(10) 
>>> kx 
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) 
>>> kx.shape 
(10,) 

>>> wx = np.arange(10).reshape(1, 10) 
>>> wx 
array([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]]) 
>>> wx.shape 
(1, 10) 

Hier ist eine verkürzte Version der relevanten Rundfunk Regeln:

Beim Betrieb auf zwei Arrays vergleicht NumPy ihre Formen elementweise. Es beginnt mit den nachlaufenden Dimensionen und arbeitet sich vorwärts. Zwei Dimensionen kompatibel sind, wenn:

  1. sie gleich sind, oder
  2. einer von ihnen 1 ist

... Die Größe des resultierenden Arrays ist die maximale Größe entlang jeder Dimension des Eingangs Arrays.

In Ihrem Fall, ein (N,) Array wird von einem (1,N) Array multipliziert, was zu einem (1,N) Array, das das Element weises Produkt der Eingänge enthält:

>>> >>> kx*wx 
array([[ 0, 1, 4, 9, 16, 25, 36, 49, 64, 81]]) 

Das hat nichts mit der Matrix zu tun Multiplikation. Die verbleibenden Operationen können nach denselben Regeln analysiert werden.

+0

Bitte überprüfen Sie die Frage jetzt. Danke für die Hilfe! – Sibi

+1

@Sibi. Nett. Ich habe meine enge Abstimmung entfernt. Aktualisierte Antwort wird bald verfügbar sein (obwohl die Antwort gesendet wird). –

+0

Ich überprüfte Sendung von dem Link, den Sie gaben, aber es sagte das Punktprodukt. Ich habe nicht verstanden, wie das Skalarprodukt einer 40000x1-Vektor- und 1x40000-Matrix auch eine 1x40000-Matrix ist. Wie auch immer, auf deine Antwort wartend! – Sibi

0

Also wx ist (1, N), X ist 2d; S ist gleich, aber mit 1 mehr Spalte.

X[:,k] ist xk ist (N,), (1d), so ist sk

xk * wx + sk * wRec die (N,)*(1,N) + (N,)*? ist;

(N,) wird bei Bedarf automatisch auf (1,N) erweitert, so dass das Ergebnis update_state auch (1,N) ist. Das Zuweisen zu S[:,k+1] sollte funktionieren, wieder, da eine 1 Dimension zu Beginn je nach Bedarf hinzugefügt werden kann.

In [120]: x=np.zeros((3,4),int) 

In [121]: x[:,0]=np.ones((1,3),int) 

In [122]: x 
Out[122]: 
array([[1, 0, 0, 0], 
     [1, 0, 0, 0], 
     [1, 0, 0, 0]]) 

Ein (N,1) assigment würde Probleme geben:

In [123]: x[:,0]=np.ones((3,1),int) 
... 
ValueError: could not broadcast input array from shape (3,1) into shape (3) 

Wenn es um die Ausstrahlung kommt (N,) Form funktioniert gut mit (1,N), aber nicht mit (N,1).

(MATLAB im Gegensatz ist immer mindestens 2d, und fügt am Ende leicht Maße am Ende hinzu).

Beachten Sie, dass ich die Zeilen- oder Spaltenvektor-Terminologie vermeiden; das Formtupel ist klarer.

Verwandte Themen