为了账号安全,请及时绑定邮箱和手机立即绑定

到位矩阵乘法numpy

到位矩阵乘法numpy

元芳怎么了 2021-05-14 23:22:13
我有一个点数组的列表,当我遍历它时,我想进行就地矩阵乘法,即我想将结果存储在同一矩阵中。该代码本质上是:for p in p_list:         # R is a 3x3 matrix     p[:,:] = np.matmul(R,p)此代码未显示错误,但结果不正确,就好像在数组中执行乘法并按计算结果进行替换一样,因此它创建了错误的输出矩阵。删除[:,:]可得出正确的乘法。1)为什么会这样呢?2)我使用[:,:]的主要原因是确保将结果存储回列表p_list中。有正确的方法(不使用中间变量)吗?
查看完整描述

3 回答

?
缥缈止盈

TA贡献2041条经验 获得超4个赞

matmul 接受一个out参数

如果p_listndarray带形状的N, 3,那么您可以一次完成整个乘法matmul

np.matmul(p_list, R.T, out=p_list)


查看完整回答
反对 回复 2021-05-25
?
红糖糍粑

TA贡献1815条经验 获得超6个赞

以@sacul的示例为例:


In [59]: R.shape

Out[59]: (3, 3)

In [60]: p_list.shape

Out[60]: (2, 3)


In [58]: np.array([np.matmul(R,p) for p in p_list])

Out[58]: 

array([[1.54190819, 2.86411033, 2.13484841],

       [3.7506842 , 6.75463885, 4.89299192]])

einsum 生成相同的(新的)数组而没有外部循环:


In [61]: np.einsum('ij,kj->ki',R,p_list)

Out[61]: 

array([[1.54190819, 2.86411033, 2.13484841],

       [3.7506842 , 6.75463885, 4.89299192]])

和一样ufunc,它接受一个out参数:


In [63]: np.einsum('ij,kj->ki',R,p_list, out=p_list)

Out[63]: 

array([[1.54190819, 2.86411033, 2.13484841],

       [3.7506842 , 6.75463885, 4.89299192]])

In [64]: p_list

Out[64]: 

array([[1.54190819, 2.86411033, 2.13484841],

       [3.7506842 , 6.75463885, 4.89299192]])

我确定它使用了一个中间缓冲区,但是应该比逐行迭代要快。与使用out相比,让它返回一个新数组要慢一些。


进行尺寸调整后,matmul可以在一个调用中执行整个计算(关键是将的最后一个暗角R与第二个和最后一个暗角配对p_list(已修改))。


In [84]: (R@p_list[:,:,None])[:,:,0]

Out[84]: 

array([[1.54190819, 2.86411033, 2.13484841],

       [3.7506842 , 6.75463885, 4.89299192]])


查看完整回答
反对 回复 2021-05-25
  • 3 回答
  • 0 关注
  • 129 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号