2013-07-11 143 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