如何在numpy中推广元素矩阵运算

时间:2015-04-20 15:40:29

标签: python numpy vectorization

假设我有两组n个向量由3xn数组V和W表示,一组n个矩阵用3x3xn数组Q表示。如何向量化操作以给我

a)范围(n)中k的n个向量Q[:,:,k]*V[:,k]的集合

b)范围(n)中k的n个标量W[:,k].T*Q[:,:,k]*V[:,k]的集合

这里的乘法被解释为矩阵乘法。无法理解我认为应该使用的einsum文档。任何澄清/解决方案将不胜感激。

1 个答案:

答案 0 :(得分:3)

  

a)范围(n)中k的n个向量Q [:,:,k] * V [:,k]的集合

np.einsum('ijk,jk->ik', Q, v)

应生成(3,n)数组。矩阵乘积和总和超过j

  

b)n个标量的集合W [:,k] .T * Q [:,:,k] * V [:,k]表示范围(n)中的k

np.einsum('ik,ijk,jk->k', W, Q, V)

我在记忆中工作,我最好的猜测你需要什么。所以我的'ij'表达可能需要调整。但试一试,让我知道它是如何工作的。


测试

In [180]: V=W=np.arange(3*n).reshape(3,n)

In [181]: Q=np.arange(3*3*n).reshape(3,3,n)

In [182]: np.einsum('ijk,jk->ik',Q,V)
Out[182]: 
array([[ 80, 107, 140, 179],
       [224, 287, 356, 431],
       [368, 467, 572, 683]])

In [183]: np.einsum('ik,ijk,jk',W,Q,V)
Out[183]: 28788    # summation over k

In [184]: np.einsum('ik,ijk,jk->k',W,Q,V)
Out[184]: array([ 3840,  5745,  8136, 11067])

有时将einsum分成几个步骤会更快,因为它会使迭代空间变得太大。我认为这不是这种情况,但这就是看起来的样子。

In [185]: np.einsum('jk,jk->k',np.einsum('ik,ijk->jk',W,Q),V)
Out[185]: array([ 3840,  5745,  8136, 11067])

并使用Jaime的评论:

In [186]: np.einsum('i...,ij...,j...',W,Q,V)
Out[186]: array([ 3840,  5745,  8136, 11067])

In [187]: np.einsum('ij...,j...->i...',Q,V)
Out[187]: 
array([[ 80, 107, 140, 179],
       [224, 287, 356, 431],
       [368, 467, 572, 683]])