我有三个矩阵W
H
和V
。我想得到keep
,它存储V
的所有列和W
的每一列之间的元素乘法,并按行求和。
(V
有6行,W
也有6行。W
的每一列(有6个元素)与V
每一列的6个元素相乘。然后将结果相加为行)
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
相乘,但我确信有人有更好的主意(或确认没有)。我尝试避免
for
循环,因为这是长算法的一部分,我希望当group
达到数百时它可以超级快。 最佳答案
似乎非常适合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