带NumPy的元素矩阵向量积

带NumPy的元素矩阵向量积,numpy,Numpy,我有一个MxN RGB图像,表示为a(M,N,3)数组a。我还有另一个(3,3)矩阵B。我想将a中的每个像素(3矢量)左乘B得到(M,N,3)输出矩阵C,这样C[I][j]=B@a[I][j]。如何在不循环通过A中的像素的情况下执行此操作?我认为您需要使用einsum进行此类操作: import numpy as np shape = 10, 20, 3 A = np.random.random(np.product(shape)).reshape(shape) B = np.random.r

我有一个MxN RGB图像,表示为a
(M,N,3)
数组
a
。我还有另一个
(3,3)
矩阵
B
。我想将
a
中的每个像素(3矢量)左乘
B
得到
(M,N,3)
输出矩阵
C
,这样
C[I][j]=B@a[I][j]
。如何在不循环通过
A
中的像素的情况下执行此操作?

我认为您需要使用
einsum
进行此类操作:

import numpy as np

shape = 10, 20, 3
A = np.random.random(np.product(shape)).reshape(shape)
B = np.random.random(9).reshape((3, 3))

print(np.einsum("ijk,lk", A, B).shape)
有关文档,请参阅。

您只需执行此操作即可

C = (B @ A[...,None]).reshape(A.shape)
让我们重写:

C[i][j] = B @ A[i][j]
作为:

实际上我不认为这是对的,因为
@
将第一个的最后一个与第二个的最后一个配对<代码>A需要额外的“虚拟”维度

实际上,它更容易表达为:

np.einsum('ijk,lk->ijl',A,B)
np.einsum('ijk,kl->ijl',A,B.T)
所以

编号:

In [33]: A = np.arange(24).reshape(2,4,3)
In [34]: B = np.arange(9).reshape(3,3)
In [35]: np.einsum('ijk,lk->ijl',A,B)
Out[35]: 
array([[[  5,  14,  23],
        [ 14,  50,  86],
        [ 23,  86, 149],
        [ 32, 122, 212]],

       [[ 41, 158, 275],
        [ 50, 194, 338],
        [ 59, 230, 401],
        [ 68, 266, 464]]])
In [36]: A@B.T
Out[36]: 
array([[[  5,  14,  23],
        [ 14,  50,  86],
        [ 23,  86, 149],
        [ 32, 122, 212]],

       [[ 41, 158, 275],
        [ 50, 194, 338],
        [ 59, 230, 401],
        [ 68, 266, 464]]])
In [37]: (B@A[...,None]).squeeze()
Out[37]: 
array([[[  5,  14,  23],
        [ 14,  50,  86],
        [ 23,  86, 149],
        [ 32, 122, 212]],

       [[ 41, 158, 275],
        [ 50, 194, 338],
        [ 59, 230, 401],
        [ 68, 266, 464]]])
A @ B.T
(B @ A[:,:,:,None]).squeeze()
In [33]: A = np.arange(24).reshape(2,4,3)
In [34]: B = np.arange(9).reshape(3,3)
In [35]: np.einsum('ijk,lk->ijl',A,B)
Out[35]: 
array([[[  5,  14,  23],
        [ 14,  50,  86],
        [ 23,  86, 149],
        [ 32, 122, 212]],

       [[ 41, 158, 275],
        [ 50, 194, 338],
        [ 59, 230, 401],
        [ 68, 266, 464]]])
In [36]: A@B.T
Out[36]: 
array([[[  5,  14,  23],
        [ 14,  50,  86],
        [ 23,  86, 149],
        [ 32, 122, 212]],

       [[ 41, 158, 275],
        [ 50, 194, 338],
        [ 59, 230, 401],
        [ 68, 266, 464]]])
In [37]: (B@A[...,None]).squeeze()
Out[37]: 
array([[[  5,  14,  23],
        [ 14,  50,  86],
        [ 23,  86, 149],
        [ 32, 122, 212]],

       [[ 41, 158, 275],
        [ 50, 194, 338],
        [ 59, 230, 401],
        [ 68, 266, 464]]])