您忘记显示数组:
In [87]: arr1
Out[87]:
array([[0, 1],
[2, 3],
[4, 5],
[6, 7]])
In [88]: arr2
Out[88]:
array([[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
In [89]: ans
Out[89]:
array([[ 8, 9, 10, 11],
[ 32, 37, 42, 47],
[ 56, 65, 74, 83],
[ 80, 93, 106, 119]])
In [90]: ans2
Out[90]:
array([[ 76, 124],
[ 98, 162]])
In [91]: ans3
Out[91]: array(238)
ans
只是常规的点矩阵乘积:
In [92]: np.dot(arr1,arr2)
Out[92]:
array([[ 8, 9, 10, 11],
[ 32, 37, 42, 47],
[ 56, 65, 74, 83],
[ 80, 93, 106, 119]])
dot
乘积之和在 的轴([1],[0])
1arr1
和轴 0 上执行arr2
(常规跨列,沿行向下)。使用 2d 'sum across ...' 短语可能会令人困惑。处理 1 或 3d 数组时更清楚。这里将匹配大小的 2 个维度相加,留下 (4,4)。
ans2
反转它们,对 4 求和,产生 (2,2):
In [94]: np.dot(arr2,arr1)
Out[94]:
array([[ 76, 98],
[124, 162]])
tensordot
刚刚转置了 2 个数组并执行了常规操作dot
:
In [95]: np.dot(arr1.T,arr2.T)
Out[95]:
array([[ 76, 124],
[ 98, 162]])
ans3
is 使用转置和重塑 ( ravel
),在两个轴上求和:
In [98]: np.dot(arr1.ravel(),arr2.T.ravel())
Out[98]: 238
通常,tensordot
使用转置和重塑的组合将问题简化为 2dnp.dot
问题。然后它可能会重塑和转置结果。
我发现尺寸控制einsum
更清晰:
In [99]: np.einsum('ij,jk->ik',arr1,arr2)
Out[99]:
array([[ 8, 9, 10, 11],
[ 32, 37, 42, 47],
[ 56, 65, 74, 83],
[ 80, 93, 106, 119]])
In [100]: np.einsum('ji,kj->ik',arr1,arr2)
Out[100]:
array([[ 76, 124],
[ 98, 162]])
In [101]: np.einsum('ij,ji',arr1,arr2)
Out[101]: 238
随着 和 的发展einsum
,matmul/@
已经tensordot
变得不那么必要了。它更难理解,并且没有任何速度或灵活性优势。不要担心理解它。
ans3
是其他 2 个答案的迹线(对角线之和):
In [103]: np.trace(ans)
Out[103]: 238
In [104]: np.trace(ans2)
Out[104]: 238