2013-07-11 67 views
2

是否有一種在NumPy中矢量化這些操作的通用方法?NumPy中的矢量化操作

In [2]: N = 8 

In [3]: ll = np.arange(8) 

In [4]: arr = np.zeros(ll.shape + (2, 2)) 

In [5]: ll.shape 
Out[5]: (8,) 

In [6]: arr.shape 
Out[6]: (8, 2, 2) 

In [7]: for ii in range(N): 
    ...:  arr[ii, :, :] = np.array(...) # 2 x 2 array function of ll[ii] 

如果該函數是LL線性操作那麼這將是微不足道的,但有沒有辦法做到這一點在一般情況下?只是把一個例子:

In [8]: for ii in range(N): 
    ...:  arr[ii, :, :] = np.array([ 
    ...:   [np.cos(ll[ii]) - 1, 0], 
    ...:   [np.sin(ll[ii]), np.cos(ll[ii]) ** 2] 
    ...:  ]) 

回答

1

你可以這樣說:

def func(x): 
    return np.array([ 
     [np.cos(x)-1,np.repeat(0, len(x))], 
     [np.sin(x), np.cos(x)**2] 
    ]) 

然後func(x)返回形狀(2, 2, 8)的數組。你可以通過​​以你想要的方向獲得它。

這隻適用於x是一維的。我認爲你可以使用np.broadcast_arrays來更高維度地工作,但目前還不確定。但基本的是,如果你想返回一個數組,你不能在某些單元格中使用向量化的numpy函數,如cos,而在其他單元格中放置字面標量(如0)。你需要用一個數組來填充標量單元,該數組的形狀來自輸入數組。

+0

謝謝您的回答,我看到了正確的方法來轉那將是'arr.transpose(2,0,1)' 。如果有更清晰的方法,我會等待其他答案,否則我會接受。 – astrojuanlu

4

組裝您arr陣列會是這樣的正確方法:

arr[:, 0, 0] = np.cos(ll) - 1 
arr[:, 0, 1] = 0 
arr[:, 1, 0] = np.sin(ll) 
arr[:, 1, 1] = np.cos(ll) ** 2 

你絕對不應該是將要存儲一個已經存在的數組中的數組列表上稱之爲np.array:這是浪費中間陣列創建,這是一個不好的做法,我懷疑它增加了代碼的清晰度。內存/性能意識的開發商可能會做這樣的事情:

np.cos(ll, out=arr[:, 0, 0]) 
arr[:, 1, 1] = arr[:, 0, 0] 
arr[:, 0, 0] -= 1 
arr[:, 0, 1] = 0 
np.sin(ll, out=arr[:, 1, 0]) 
arr[:, 1, 1] *= arr[:, 1, 1] 

但這樣做往往不是屬於過早優化類別。

你也應該真的不使用ll作爲變量名...

+2

+1爲變量名稱... –

+0

變量名稱有什麼問題? :) – astrojuanlu

+0

我預計在一個班輪矢量化整個事情的一些方法,但現在你帶來了性能的事情,我可能會做一些基準測試與您建議的解決方案。謝謝! – astrojuanlu