【问题标题】:Numpy array muliplicationNumpy 数组乘法
【发布时间】:2022-12-13 00:58:59
【问题描述】:

我有两个输入数组和一个输出数组,如下所示:

M=np.array([[1,2,3],[3,4,5],[6,7,8]])
u=np.array([[1,2,3],[4,5,7],[2,4,9]])
res=np.zeros((3,))

我想做以下计算:

for i in range(3):
      res[i]=np.matmul(np.matmul(u[0:,i].T,M),u[0:,i])
#res=array([ 231.,  594., 1957.])

我可以不做 for 循环就做吗,因为 for 循环在较大的矩阵中会花费很多时间

所以目标是实现更快的方法

【问题讨论】:

  • 没有更快的方法。加快速度的唯一方法是并行计算并为每个条目创建一个线程。
  • 我不同意,如果你正确地使用矢量化,你可以做得更快!

标签: numpy multidimensional-array matrix-multiplication array-broadcasting vector-multiplication


【解决方案1】:

最直观的方法可能是通过np.einsum

res = np.einsum('ki,kl,li->i', u, M, u)

【讨论】:

  • 谢谢,确实更快。在以下情况下:M=[11,11] u=[11,5590] for loop: 0.0209 sec enum: 0.00199 sec
【解决方案2】:

坚持使用 matmul,您将 u 的最后一个维度视为一个“批次”,即您在循环中迭代的那个。如果我们将 u 重塑为 3d,首先使用该批次维度:

In [430]: u1 = u.T[:,None,:]; u2 = u.T[:,:,None]

In [431]: u1@M@u2
Out[431]: 
array([[[ 231]],

       [[ 594]],

       [[1957]]])

这是 (3,1,1),首先是批量维度,最后一个二维是矩阵乘积。我们可以把它们挤出来:

In [432]: np.squeeze(u1@M@u2)
Out[432]: array([ 231,  594, 1957])

matmul 使用 (n,1,3)、(3,3) 和 (n,3,1) 生成 (n,1,1),乘积之和在份额 3 上。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-27
    • 2015-07-03
    • 1970-01-01
    相关资源
    最近更新 更多