矩阵将第一维的每对二维阵列与einsum相乘

时间:2017-10-12 17:35:43

标签: python numpy

我有两个大小相同的三维数组ab

np.random.seed([3,14159])
a = np.random.randint(10, size=(4, 3, 2))
b = np.random.randint(10, size=(4, 3, 2))
print(a)

[[[4 8]
  [1 1]
  [9 2]]

 [[8 1]
  [4 2]
  [8 2]]

 [[8 4]
  [9 4]
  [3 4]]

 [[1 5]
  [1 2]
  [6 2]]]
print(b)

[[[7 7]
  [1 1]
  [7 8]]

 [[7 4]
  [8 0]
  [0 9]]

 [[3 8]
  [7 7]
  [2 6]]

 [[3 1]
  [9 3]
  [0 5]]]

我想从

中获取第一个数组
a[0]

[[4 8]
 [1 1]
 [9 2]]

第一个来自b

b[0]

[[7 7]
 [1 1]
 [7 8]]

并返回此

a[0].T.dot(b[0])

[[ 92 101]
 [ 71  73]]

但我希望在整个第一维度上做到这一点。我以为我可以使用np.einsum

np.einsum('abc,ade->ace', a, b)

[[[210 224]
  [165 176]]

 [[300 260]
  [ 75  65]]

 [[240 420]
  [144 252]]

 [[ 96  72]
  [108  81]]]

这是正确的形状,但不是值。

我希望得到这个:

np.array([x.T.dot(y).tolist() for x, y in zip(a, b)])

[[[ 92 101]
  [ 71  73]]

 [[ 88 104]
  [ 23  22]]

 [[ 93 145]
  [ 48  84]]

 [[ 12  34]
  [ 33  21]]]

2 个答案:

答案 0 :(得分:2)

矩阵乘法相当于乘以中轴的乘积之和,因此两个数组的索引b应该相同:(即将ade更改为{{1 }}):

abe

当输入数组的输出数组中缺少索引下标时, 他们是独立总结的。也就是说,

In [40]: np.einsum('abc,abe->ace', a, b)
Out[40]: 
array([[[ 92, 101],
        [ 71,  73]],

       [[ 88, 104],
        [ 23,  22]],

       [[ 93, 145],
        [ 48,  84]],

       [[ 12,  34],
        [ 33,  21]]])

相当于

np.einsum('abc,ade->ace', a, b)

答案 1 :(得分:2)

这是一个np.matmul,因为我们需要将a的第二个轴推回到最后,以便sum-reducedb到第二个轴,同时保持第一个轴对齐 -

np.matmul(a.swapaxes(1,2),b) 

示意地说:

开始时:

a   :  M x N X R1
b   :  M x N X R2

使用交换轴:

a   :  M x R1 X [N]
b   :  M x [N] X R2

括号中的轴得到sum-reduced,留给我们:

out :   M x R1 X R2

在Python 3.x上,使用@ operator -

处理matmul
a.swapaxes(1,2) @ b