红糖糍粑
以@sacul的示例为例:In [59]: R.shapeOut[59]: (3, 3)In [60]: p_list.shapeOut[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_listOut[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]])