Numpy将向量数组当作矩阵相乘

li9yvcax  于 2022-12-18  发布在  其他
关注(0)|答案(1)|浏览(91)

我正在用python做一个3d渲染器,一个非常常见的操作是向量数组乘以矩阵,我知道numpys @运算符和board casting,所以我只做了matrix @ arrayOfVectors,看起来不错,但是输出错误,我意识到numpy把向量的array当作矩阵(在这个例子中是4X 8),并且它是相应地将它们相乘。我已经切换到使用X1 M2 N1 X循环,这确实有一些优点,但我明白这要慢得多,并且如果可能的话应该避免。我想找到一种方法来将矩阵应用于向量数组中的每个向量,而且在某些情况下,还会在之后将每个矢量除以它的w分量,有没有办法像整洁的matrix @ arrayOfVectors那样做,或者我必须求助于for vector in arrayOfVectors: matrix @ array

n53p2ov0

n53p2ov01#

In [14]: A = np.arange(12).reshape(3,4); V = np.arange(8).reshape(2,4)

第一维是不同的,所以direct matmul不仅不能给予想要的结果,而且会出错,它试图对2个数组进行矩阵乘法运算:

In [15]: A@V
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Input In [15], in <cell line: 1>()
----> 1 A@V

ValueError: matmul: Input operand 1 has a mismatch in its core dimension 0, with gufunc signature (n?,k),(k,m?)->(n?,m?) (size 2 is different from 4)

您需要的是将V的第一维视为“批处理”:

In [17]: [A@v for v in V]
Out[17]: [array([14, 38, 62]), array([ 38, 126, 214])]


我们通过将V作为3d阵列来实现这一点-请阅读matmul文档:

In [18]: A@V[:,:,None]
Out[18]: 
array([[[ 14],
        [ 38],
        [ 62]],

       [[ 38],
        [126],
        [214]]])

In [19]: _.shape
Out[19]: (2, 3, 1)

如有必要,我们可以删除尾随大小1维(squeeze
使用einsum很容易指定此类尺寸:

In [20]: np.einsum('ij,kj->ik',A,V)
Out[20]: 
array([[ 14,  38],
       [ 38, 126],
       [ 62, 214]])

我可以用ki来得到(2,3)的答案。

相关问题