【问题标题】:Is it possible to multiply all of each column in matrix A by each column of matrix B without for loop?是否可以在没有 for 循环的情况下将矩阵 A 中的所有列乘以矩阵 B 的每一列?
【发布时间】:2018-02-05 07:33:00
【问题描述】:

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

(V 有 6 行,W 也有 6 行。W 的每一列(有 6 个元素)乘以 Vcolumn 的 每一列 的 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 达到数百个时它可以超快。

【问题讨论】:

    标签: python python-2.7 numpy matrix vectorization


    【解决方案1】:

    似乎非常适合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
    

    【讨论】:

    • 哇!以前从来不知道这一点。你介意解释一下下标之间的箭头吗?如果我不想使用所有矩阵,我只需定义 np.einsum('ij,ik->ki',V,W[:,0:2])?
    • @Jan This comment 可能有助于理解下标符号。是的,如果您只使用 W 的前 2 列,np.einsum('ij,ik->ki',V,W[:,0:2]) 应该可以工作。
    • 非常感谢。让我再问一件事。如果在keep 中的sum 之前,我有一个分母; keep = np.vstack([keep, sum((V.T*W[:,k]).T/deno)]) 其中deno = np.dot(W,H)keep 必须更改为keep = np.array([]).reshape(0,5))。如何在np.einsum中输入分母?或者如果我有分裂,我必须使用其他东西?
    • @Jan 就这样吧:np.einsum('ij,ik->kj',V/deno,W).
    猜你喜欢
    • 1970-01-01
    • 2015-06-23
    • 2014-03-03
    • 2018-06-29
    • 2012-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多