numpy矢量化而不是循环

时间:2017-09-21 12:28:50

标签: numpy vectorization

我有以下等式:

enter image description here

其中v,mu是| R ^ 3,其中Sigma是| R ^(3x3),其中结果是标量值。在numpy中实现这个是没有问题的:

result = np.transpose(v - mu) @ Sigma_inv @ (v - mu)

现在我有一堆v向量(让我们称之为V \ in | R ^ 3xn)我想 喜欢以矢量化方式执行上述等式,以便如此 结果我得到一个新的向量Result \ in | R ^ 1xn。

# pseudocode
Result = np.zeros((n, 1))
for i,v in V:
    Result[i,:] = np.transpose(v - mu) @ Sigma_inv @ (v - mu)

我查看了 np.vectorize ,但文档表明它与循环所有我不想做的条目一样。什么是优雅的矢量化解决方案?

作为一个侧节点:n可能非常大,而且| R ^ nxn矩阵肯定不适合我的记忆!

编辑:工作代码示例

import numpy as np

S = np.array([[1, 2], [3,4]])
V = np.array([[10, 11, 12, 13, 14, 15],[20, 21, 22, 23, 24, 25]])

Res = np.zeros((V.shape[1], 1))
for i in range(V.shape[1]):
    v = np.transpose(np.atleast_2d(V[:,i]))
    Res[i,:] = (np.transpose(v) @ S @ v)[0][0]

print(Res)

4 个答案:

答案 0 :(得分:4)

使用matrix-multiplicationnp.einsum -

的组合
np.einsum('ij,ij->j',V,S.dot(V))

答案 1 :(得分:2)

这对你有用吗?

res = np.diag(V.T @ S @ V).reshape(-1, 1)

它似乎提供了您想要的相同结果。

import numpy as np

S = np.array([[1, 2], [3,4]])
V = np.array([[10, 11, 12, 13, 14, 15],[20, 21, 22, 23, 24, 25]])

Res = np.zeros((V.shape[1], 1))
for i in range(V.shape[1]):
    v = np.transpose(np.atleast_2d(V[:,i]))
    Res[i,:] = (np.transpose(v) @ S @ v)[0][0]

res = np.diag(V.T @ S @ V).reshape(-1, 1)

print(np.all(np.isclose(Res, res)))
# output: True

尽管使用np.einsum可能存在更高效的内存解决方案。

答案 2 :(得分:2)

这是一个简单的解决方案:

import numpy as np

S = np.array([[1, 2], [3,4]])
V = np.array([[10, 11, 12, 13, 14, 15],[20, 21, 22, 23, 24, 25]])

Res = np.sum((V.T @ S) * V.T, axis=1)

答案 3 :(得分:0)

这是矩阵/向量堆栈的乘法。将S和V带入正确的形状后,numpy.matmul可以做到这一点:

S = S[np.newaxis, :, :]
VT = V.T[:, np.newaxis, :]
V = VT.transpose(0, 2, 1)    

tmp = np.matmul(S, V)
Res = np.matmul(VT, tmp)

print(Res)
#[[[2700]]
# [[3040]]
# [[3400]]
# [[3780]]
# [[4180]]
# [[4600]]]