2

在 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]
   ...:     ])
4

2 回答 2

5

组装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其用作变量名...

于 2013-07-11T13:42:02.737 回答
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)将返回一个 shape 数组(2, 2, 8)。您可以使用func(x).T.

这只适用于x一维的情况。我认为您可以使用 来解决更高维度的问题np.broadcast_arrays,但目前不确定具体如何。然而,基本的事情是,如果你想返回一个数组,你不能像cos在某些单元格中那样使用向量化的 numpy 函数,而在其他单元格中放置文字标量(如 0)。您需要用一个形状从输入数组派生的数组填充标量单元。

于 2013-07-11T07:48:59.090 回答