You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现3D矩阵与2D矩阵的对应行Numpy点积运算?

问题

我有一个形状为(2, 10, 3)的3D数组normal,以及一个形状为(2, 3)的2D数组t,具体数据如下:

print(t) #2d array
# Output:
[[1.003   2.32    3.11   ]
 [1.214   5.32    2.13241]]

print(normal) #3d array
# Output:
[[[0.69908573 0.0826756  0.84485978]
  [0.51058213 0.4052637  0.5068118 ]
  [0.45974276 0.25819549 0.10780089]
  [0.27484999 0.33367648 0.128262  ]
  [0.35963389 0.77600065 0.89393939]
  [0.46937506 0.59291623 0.06620307]
  [0.87603987 0.44414505 0.83394174]
  [0.83186093 0.62491876 0.38160734]
  [0.96819897 0.80183442 0.75102768]
  [0.54182908 0.19403844 0.07925769]]

 [[2.82248573 3.2341756  0.96825978]
  [2.63398213 3.5567637  0.6302118 ]
  [2.58314276 3.40969549 0.23120089]
  [2.39824999 3.48517648 0.251662  ]
  [2.48303389 3.92750065 1.01733939]
  [2.59277506 3.74441623 0.18960307]
  [2.99943987 3.59564505 0.95734174]
  [2.95526093 3.77641876 0.50500734]
  [3.09159897 3.95333442 0.87442768]
  [2.66522908 3.34553844 0.20265769]]]

需要让2D数组t中的每一行,与3D数组normal中对应的矩阵进行点积运算,最终得到一个形状为(2, 10)的数组——第n行包含t的第n行与normal的第n个矩阵中10个向量的点积结果。预期输出如下:

[0.62096458 0.62618459 0.37528887 0.5728386  1.19634398 0.79620507
 1.997884   0.75229492 1.2236496  0.4210626 ]
[2.96347746 3.30738892 3.50596579 4.93082295 5.33811805 4.44872493
 7.33480393 4.19173472 4.7406248  7.83229689]

解决方案

以下是三种基于NumPy的实现方式,都能满足需求:

方法1:使用np.einsum

通过爱因斯坦求和符号清晰指定维度运算关系,适合多维数组的点积场景:

import numpy as np

# 构造示例数组
t = np.array([[1.003, 2.32, 3.11], [1.214, 5.32, 2.13241]])
normal = np.array([
    [[0.69908573, 0.0826756, 0.84485978],
     [0.51058213, 0.4052637, 0.5068118],
     [0.45974276, 0.25819549, 0.10780089],
     [0.27484999, 0.33367648, 0.128262],
     [0.35963389, 0.77600065, 0.89393939],
     [0.46937506, 0.59291623, 0.06620307],
     [0.87603987, 0.44414505, 0.83394174],
     [0.83186093, 0.62491876, 0.38160734],
     [0.96819897, 0.80183442, 0.75102768],
     [0.54182908, 0.19403844, 0.07925769]],
    [[2.82248573, 3.2341756, 0.96825978],
     [2.63398213, 3.5567637, 0.6302118],
     [2.58314276, 3.40969549, 0.23120089],
     [2.39824999, 3.48517648, 0.251662],
     [2.48303389, 3.92750065, 1.01733939],
     [2.59277506, 3.74441623, 0.18960307],
     [2.99943987, 3.59564505, 0.95734174],
     [2.95526093, 3.77641876, 0.50500734],
     [3.09159897, 3.95333442, 0.87442768],
     [2.66522908, 3.34553844, 0.20265769]]
])

result = np.einsum('ij,ijk->ik', t, normal)
print(result)

'ij,ijk->ik'表示:对t的第i行第j列元素,与normal的第i个矩阵第k个向量的第j列元素相乘后求和,最终得到第i行第k列的结果,完全匹配需求。

方法2:使用np.matmul

调整t的维度后进行矩阵乘法,再去除多余维度:

# 将t从(2,3)转为(2,1,3),与转置后的normal(2,3,10)做矩阵乘法,最后压缩维度
result = np.matmul(t[:, np.newaxis, :], normal.transpose(0,2,1)).squeeze()
print(result)

更简洁的写法:

result = np.matmul(t[:, None], normal.swapaxes(1,2)).squeeze()

方法3:广播相乘后求和

利用NumPy广播机制,让对应元素相乘后对最后一个维度求和:

# 扩展t的维度为(2,1,3),与normal(2,10,3)广播相乘,再对第3维求和
result = (t[:, np.newaxis, :] * normal).sum(axis=-1)
print(result)

这种方式逻辑直观,容易理解多维数组的运算过程。

以上三种方法都能输出符合预期的(2,10)形状数组。

内容的提问来源于stack exchange,提问作者Aayush

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 06:54:25