2014-11-24 115 views
2

我很難進入numpy。我最終想要的是一個由矩陣變換的向量的簡單抖動圖。我讀過很多次只是使用矩陣的數組,足夠公平。我已經得到了X一meshgrid和y座標Numpy:將一個矩陣與一組向量相乘

X,Y = np.meshgrid(np.arange(0,10,2),np.arange(0,10,1)) 
a = np.array([[1,0],[0,1.1]]) 

但即使是谷歌搜索,並嘗試了兩個多小時後,我無法擺脫的a矩陣乘法而且每個向量的所得載體。我知道顫抖將分量長度作爲輸入,所以進入顫抖函數的結果向量應該是類似於x分量的np.dot(a, [X[i,j], Y[i,j]]) - X[i,j],其中i和j遍歷範圍。

我當然可以在循環中編程,但numpy有很多內建工具可以使這些向量化的東西得心應手,我相信有更好的方法。

編輯:好的,這裏是循環版本。

import numpy as np 
import matplotlib.pyplot as plt 

plt.figure(figsize=(10,10)) 

n=10 
X,Y = np.meshgrid(np.arange(-5,5),np.arange(-5,5)) 
print("val test", X[5,3]) 
a = np.array([[0.5,0],[0,1.3]]) 
U = np.zeros((n,n)) 
V = np.zeros((n,n)) 
for i in range(10): 
    for j in range(10): 
     product = np.dot(a, [X[i,j], Y[i,j]]) #matrix with vector 
     U[i,j] = product[0]-X[i,j] # have to substract the position since quiver accepts magnitudes 
     V[i,j] = product[1]-Y[i,j] 

Q = plt.quiver(X,Y, U, V) 
+0

你期望結果看起來像什麼? a.shape =(2,2),X.shape =(10,5),Y.shape =(10,5)'。我沒有明白你的觀點... – jkalden 2014-11-24 13:46:45

+0

你可以在循環中顯示一個簡單的版本(以便更容易地計算出你正在嘗試做什麼)? – atomh33ls 2014-11-24 13:51:04

+0

完成。這實際上只是一個矢量場的矩陣,並且結果通過顫動箭頭可視化 – Basti 2014-11-24 14:03:32

回答

3

您可以做矩陣乘法「手動」使用NumPy的廣播是這樣的:

import numpy as np 
import matplotlib.pyplot as plt 

X,Y = np.meshgrid(np.arange(-5,5), np.arange(-5,5)) 
a = np.array([[0.5, 0], [0, 1.3]]) 

U = (a[0,0] - 1)*X + a[0,1]*Y 
V = a[1,0]*X + (a[1,1] - 1)*Y 

Q = plt.quiver(X, Y, U, V) 

,或者如果你想使用np.dot你必須彙整XY陣列,並將它們結合起來,適當的形狀如下:

import numpy as np 
import matplotlib.pyplot as plt 

X,Y = np.meshgrid(np.arange(-5,5), np.arange(-5,5)) 
a = np.array([[0.5, 0], [0, 1.3]]) 

U,V = np.dot(a-np.eye(2), [X.ravel(), Y.ravel()]) 

Q = plt.quiver(X, Y, U, V) 
+0

Humm,我明白這一點。但是這兩種情況都非常有限,對嗎?首先是手寫矩陣乘法。這很不好,不適合任何更高維度等等。第二個是依靠零。 – Basti 2014-11-24 17:13:26

+0

這兩種情況都適用於2D。對於3D,它應該是'U,V,W = np.dot(a-np.eye(3),[X.ravel(),Y.ravel(),Z.ravel()])' – Ondro 2014-11-24 17:22:24

+0

ooh現在我得到了代碼,謝謝! – Basti 2014-11-24 17:30:56

0

我一直在努力解決同一個問題,並最終使用numpy.matrix類。考慮下面的例子。

import numpy as np 

>>> transformation_matrix = np.array([(1, 0, 0, 1), 
...         (0, 1, 0, 0), 
...         (0, 0, 1, 0), 
...         (0, 0, 0, 1)]) 
>>> coordinates = np.array([(0,0,0), 
...       (1,0,0)]) 
>>> coordinates = np.hstack((coordinates, np.ones((len(coordinates), 1)))) 
>>> coordinates 
array([[ 0., 0., 0., 0.], 
     [ 1., 0., 0., 0.]]) 

在這種情況下,numpy.matrix類幫助。以下代碼通過將座標轉置爲列向量以及numpy.matrix類的指定矩陣乘法超載來給出預期結果。

>>> (np.asmatrix(transformation_matrix) * np.asmatrix(coordinates).T).T 
matrix([[ 1., 0., 0., 1.], 
     [ 2., 0., 0., 1.]]) 
1

作爲docs says,多維數據np.mul(或@)工作在以下方式:

對於N維它結束的最後一個軸和第二到和積b的-last:

dot(a, b)[i,j,k,m] = sum(a[i,j,:] * b[k,:,m]) 

這不是我們想在這裏。但是,有一些簡單的替代方案不涉及平展 - 解壓或手動矩陣乘法:np.tensordotnp.einsum

第一種是直接從the docs採取了一個例子:

做最左邊的指標,而不是最右邊的一個矩陣,矩陣的產品,你可以做np.einsum('ij...,jk...->ik...', a, b)

import numpy as np 
import matplotlib.pyplot as plt 

X,Y = np.meshgrid(np.arange(-5,5), np.arange(-5,5)) 
a = np.array([[0.5, 0], [0, 1.3]]) 

U, V = np.einsum('ij...,jk...->ik...', a - np.eye(2), np.array([X, Y])) 
Q = plt.quiver(X, Y, U, V) 

第二種是簡單np.tensordot應用。我們只是教它將第一個參數的第二個軸(colums)和第一個參數的第一個軸(行)相加。

import numpy as np 
import matplotlib.pyplot as plt 

X,Y = np.meshgrid(np.arange(-5,5), np.arange(-5,5)) 
a = np.array([[0.5, 0], [0, 1.3]]) 

U, V = np.tensordot(a - np.eye(2), np.array([X, Y]), axes=(1, 0)) 
plt.quiver(X, Y, U, V)