是否有可能将矩阵A中每列的所有列乘以矩阵B的每一列而不进行循环?

时间:2017-08-28 05:07:38

标签: python python-2.7 numpy matrix vectorization

我有三个矩阵W HV。我希望得到keep,它存储V的所有列与W的每列之间的元素乘法,并逐行求和。

V有6行,W也有6行。W的每列(有6个元素)乘以每个的6个元素V列的列。然后按行汇总结果

W = np.random.randint(4,6, size=(6, 4))
H = np.random.randint(1,3, size=(4, 5))
V = np.dot(W,H) + 1    
keep = np.array([]).reshape(0,6)

print W
>>[[4 4 5 5]
 [4 4 4 4]
 [4 5 5 4]
 [4 5 5 5]
 [5 4 4 5]
 [5 4 4 5]]
print V
>>[[28 33 32 37 24]
 [25 29 29 33 21]
 [28 33 33 37 24]
 [30 35 34 39 25]
 [28 32 32 37 23]
 [28 32 32 37 23]]

# I want the result from only two from four rows of W
group = 2
for k in xrange(group):
    # multiply all of each column of V by k-th column of W and sum in row
    keep = np.vstack([keep, sum(V[:,:].T*W[:,k])])

print keep, keep.shape
>>[[ 616.  548.  620.  652.  760.  760.]
  [ 616.  548.  775.  815.  608.  608.]] (2L, 6L)

我想知道这可以在没有for循环的情况下完成吗?与sum(V[:,:].T*W[:,0:1]一样,虽然我认为这是不可能的,因为W的每一列都必须逐步增加矩阵V,我相信有人有更好的想法(或确认它可以' T)。

我尽量避免for循环,因为这是长算法的一部分,我希望当group达到数百时,它可以超快。

1 个答案:

答案 0 :(得分:2)

似乎非常适合np.einsum,因为我们需要保持第一个轴在两个输入之间保持对齐并将其保留在输出中 -

np.einsum('ij,ik->ki',V,W)

示例运行 -

In [2]: W = np.random.randint(4,6, size=(6, 4))
   ...: H = np.random.randint(1,3, size=(4, 5))
   ...: V = np.dot(W,H) + 1    
   ...: keep = np.array([]).reshape(0,6)
   ...: 

In [5]: group = W.shape[1]
   ...: for k in xrange(group):
   ...:     # multiply all of each column of V by k-th column of W and sum in row
   ...:     keep = np.vstack([keep, sum(V[:,:].T*W[:,k])])
   ...:     

In [6]: np.allclose(keep, np.einsum('ij,ik->ki',V,W))
Out[6]: True