使用 numpy einsum 计算矩阵列向量的内积
Using numpy einsum to compute inner product of column-vectors of a matrix
假设我有一个像这样的 numpy 矩阵:
[[ 1 2 3]
[ 10 100 1000]]
我想计算每一列与其自身的内积,所以结果是:
[1*1 + 10*10 2*2 + 100*100 3*3 + 1000*1000] == [101, 10004, 1000009]
我想知道这是否可以使用 einsum
函数(并更好地理解它)。
到目前为止,我能得到的最接近的结果是:
import numpy as np
arr = np.array([[1, 2, 3], [10, 100, 1000]])
res = np.einsum('ij,ik->jk', arr, arr)
# [[ 101 1002 10003]
# [ 1002 10004 100006]
# [ 10003 100006 1000009]]
对角线包含预期结果,但我想知道是否可以避免边缘计算。
使用np.einsum
,像这样-
np.einsum('ij,ij->j',arr,arr)
样本运行-
In [243]: np.einsum('ij,ij->j',arr,arr)
Out[243]: array([ 101, 10004, 1000009])
或者用 np.sum
-
In [244]: (arr**2).sum(0)
Out[244]: array([ 101, 10004, 1000009])
或者用 numexpr
module -
In [248]: import numexpr as ne
In [249]: ne.evaluate('sum(arr**2,0)')
Out[249]: array([ 101, 10004, 1000009])
从 .
中间一步,您可以直观地理解您在这里的期望
In [19]: arr
Out[19]:
array([[ 1, 2, 3],
[ 10, 100, 1000]])
# simply take element-wise product with the array itself
In [20]: np.einsum('ij, ij -> ij', arr, arr)
Out[20]:
array([[ 1, 4, 9],
[ 100, 10000, 1000000]])
但是,这并没有给出您预期的结果。因此,如果您观察到上述结果,我们只需要 沿第一个维度 (即轴 0)求和。因此,我们在 einsum 结果中省略 ->
之后的下标 i
,这意味着我们要求它沿该轴求和,并产生预期结果:
In [21]: np.einsum('ij, ij -> j', arr, arr)
Out[21]: array([ 101, 10004, 1000009])
P.S。另外,对于 np.einsum
, see the detailed discussion here: understanding-numpy-einsum
的一般理解
假设我有一个像这样的 numpy 矩阵:
[[ 1 2 3]
[ 10 100 1000]]
我想计算每一列与其自身的内积,所以结果是:
[1*1 + 10*10 2*2 + 100*100 3*3 + 1000*1000] == [101, 10004, 1000009]
我想知道这是否可以使用 einsum
函数(并更好地理解它)。
到目前为止,我能得到的最接近的结果是:
import numpy as np
arr = np.array([[1, 2, 3], [10, 100, 1000]])
res = np.einsum('ij,ik->jk', arr, arr)
# [[ 101 1002 10003]
# [ 1002 10004 100006]
# [ 10003 100006 1000009]]
对角线包含预期结果,但我想知道是否可以避免边缘计算。
使用np.einsum
,像这样-
np.einsum('ij,ij->j',arr,arr)
样本运行-
In [243]: np.einsum('ij,ij->j',arr,arr)
Out[243]: array([ 101, 10004, 1000009])
或者用 np.sum
-
In [244]: (arr**2).sum(0)
Out[244]: array([ 101, 10004, 1000009])
或者用 numexpr
module -
In [248]: import numexpr as ne
In [249]: ne.evaluate('sum(arr**2,0)')
Out[249]: array([ 101, 10004, 1000009])
从
In [19]: arr
Out[19]:
array([[ 1, 2, 3],
[ 10, 100, 1000]])
# simply take element-wise product with the array itself
In [20]: np.einsum('ij, ij -> ij', arr, arr)
Out[20]:
array([[ 1, 4, 9],
[ 100, 10000, 1000000]])
但是,这并没有给出您预期的结果。因此,如果您观察到上述结果,我们只需要 沿第一个维度 (即轴 0)求和。因此,我们在 einsum 结果中省略 ->
之后的下标 i
,这意味着我们要求它沿该轴求和,并产生预期结果:
In [21]: np.einsum('ij, ij -> j', arr, arr)
Out[21]: array([ 101, 10004, 1000009])
P.S。另外,对于 np.einsum
, see the detailed discussion here: understanding-numpy-einsum