将 3D 数组与 2D 数组相乘
Multiply a 3D array with a 2D array
我有一个 3D numpy 数组,我想将它与一个 2D 数组相乘,3D 如下所示:
C= np.zeros((3, 2, 2))
C[0][0] = [0,0]
C[0][1] = [0,1]
C[1][0] = [1,0]
C[1][1] = [1,1]
C[2][0] = [1,2]
C[2][1] = [2,1]
二维数组如下所示:
V = np.zeros((3,2))
V[0][0] = 1
V[0][1] = 2
V[1][0] = 1
V[1][1] = 3
V[2][0] = 4
V[2][1] = 5
结果R
是一个 2X2 二维数组(总共 4 个元素)R=[[5,8],[13,10]]
其中:
R[0] = V[0][0]*C[0][0]+V[1][0]*C[1][0]+V[2][0]*C[2][0] = [5,8] (first row of R)
R[1] = V[0][1]*C[0][1]+V[1][1]*C[1][1]+V[2][1]*C[2][1] = [13,10] (second row of R)
这只是一个示例,我如何通过 V
和 C
(没有 for 循环!)使用 numpy 矩阵乘法运算得到 R
。请帮忙!
不好意思我后来做了一些编辑,评论是老例子,现在应该可以了
你的例子令人困惑。为什么你说你的预期结果是 [[1, 0], [5, 10]]
但在你的例子中你还说 R
应该是 [[5, 8], [13, 10]]
?
我希望这只是您的错字,因为从您的示例中并不清楚您是如何从一个到另一个的。
无论如何:
(V.T * C.T).sum(axis=2).T
输出:
array([[ 5., 8.],
[13., 10.]])
In [20]: C # (3,2,2)
Out[20]:
array([[[0, 0],
[0, 1]],
[[1, 0],
[1, 1]],
[[1, 2],
[2, 1]]])
In [21]: V # (3,2)
Out[21]:
array([[1., 2.],
[1., 3.],
[4., 5.]])
将 V
展开为 (3,2,1)。这个 broadcasts
与 C
产生一个 (3,2,2):
In [22]: C * V[:,:,None]
Out[22]:
array([[[ 0., 0.],
[ 0., 2.]],
[[ 1., 0.],
[ 3., 3.]],
[[ 4., 8.],
[10., 5.]]])
并在第一个轴上求和得到 (2,2) 结果:
In [23]: (C * V[:,:,None]).sum(axis=0)
Out[23]:
array([[ 5., 8.],
[13., 10.]])
这个答案清理了@ddjohns 的答案;他做了艰苦的工作。
sum-of-products可以用einsum
表示为:
In [24]: np.einsum('ijk,ij->jk',C,V)
Out[24]:
array([[ 5., 8.],
[13., 10.]])
重新排序轴,我们可以将其表示为更常规的sum-of-products:
In [25]: np.einsum('jki,ji->jk',C.transpose(1,2,0),V.transpose(1,0))
Out[25]:
array([[ 5., 8.],
[13., 10.]])
并用它来将其转换为 matmul
:
In [28]: (C.transpose(1,2,0)@V.transpose(1,0)[:,:,None]).squeeze(2)
Out[28]:
array([[ 5., 8.],
[13., 10.]])
[28]可能是最快的,但是[23]可能更容易理解。
我有一个 3D numpy 数组,我想将它与一个 2D 数组相乘,3D 如下所示:
C= np.zeros((3, 2, 2))
C[0][0] = [0,0]
C[0][1] = [0,1]
C[1][0] = [1,0]
C[1][1] = [1,1]
C[2][0] = [1,2]
C[2][1] = [2,1]
二维数组如下所示:
V = np.zeros((3,2))
V[0][0] = 1
V[0][1] = 2
V[1][0] = 1
V[1][1] = 3
V[2][0] = 4
V[2][1] = 5
结果R
是一个 2X2 二维数组(总共 4 个元素)R=[[5,8],[13,10]]
其中:
R[0] = V[0][0]*C[0][0]+V[1][0]*C[1][0]+V[2][0]*C[2][0] = [5,8] (first row of R)
R[1] = V[0][1]*C[0][1]+V[1][1]*C[1][1]+V[2][1]*C[2][1] = [13,10] (second row of R)
这只是一个示例,我如何通过 V
和 C
(没有 for 循环!)使用 numpy 矩阵乘法运算得到 R
。请帮忙!
不好意思我后来做了一些编辑,评论是老例子,现在应该可以了
你的例子令人困惑。为什么你说你的预期结果是 [[1, 0], [5, 10]]
但在你的例子中你还说 R
应该是 [[5, 8], [13, 10]]
?
我希望这只是您的错字,因为从您的示例中并不清楚您是如何从一个到另一个的。
无论如何:
(V.T * C.T).sum(axis=2).T
输出:
array([[ 5., 8.],
[13., 10.]])
In [20]: C # (3,2,2)
Out[20]:
array([[[0, 0],
[0, 1]],
[[1, 0],
[1, 1]],
[[1, 2],
[2, 1]]])
In [21]: V # (3,2)
Out[21]:
array([[1., 2.],
[1., 3.],
[4., 5.]])
将 V
展开为 (3,2,1)。这个 broadcasts
与 C
产生一个 (3,2,2):
In [22]: C * V[:,:,None]
Out[22]:
array([[[ 0., 0.],
[ 0., 2.]],
[[ 1., 0.],
[ 3., 3.]],
[[ 4., 8.],
[10., 5.]]])
并在第一个轴上求和得到 (2,2) 结果:
In [23]: (C * V[:,:,None]).sum(axis=0)
Out[23]:
array([[ 5., 8.],
[13., 10.]])
这个答案清理了@ddjohns 的答案;他做了艰苦的工作。
sum-of-products可以用einsum
表示为:
In [24]: np.einsum('ijk,ij->jk',C,V)
Out[24]:
array([[ 5., 8.],
[13., 10.]])
重新排序轴,我们可以将其表示为更常规的sum-of-products:
In [25]: np.einsum('jki,ji->jk',C.transpose(1,2,0),V.transpose(1,0))
Out[25]:
array([[ 5., 8.],
[13., 10.]])
并用它来将其转换为 matmul
:
In [28]: (C.transpose(1,2,0)@V.transpose(1,0)[:,:,None]).squeeze(2)
Out[28]:
array([[ 5., 8.],
[13., 10.]])
[28]可能是最快的,但是[23]可能更容易理解。