[英]Computing product of ith row of array1 and ith column of array2 - NumPy
I have a matrix M1
of shape (N*2)
and another matrix M2
(2*N)
, I want to obtain a result of (N)
, each element i
is the product of i
th row of M1
and i
th column of M2
.我有一个形状为
(N*2)
的矩阵M1
和另一个矩阵M2
(2*N)
,我想获得(N)
的结果,每个元素i
是M1
第i
行和第i
列的乘积M2
。 I tried to use dot in NumPy, but it can only give me the matrix multiplication result, which is (N*N)
, of course, I can take the diagonal which is what I want, I would like to know is there a better way to do this?我尝试在NumPy中使用点,但它只能给我矩阵乘法结果,即
(N*N)
,当然,我可以取我想要的对角线,我想知道有没有更好的如何做到这一点?
Approach #1方法#1
You can use np.einsum
-您可以使用
np.einsum
-
np.einsum('ij,ji->i',M1,M2)
Explanation :解释 :
The original loopy solution would look something like this -原始的循环解决方案看起来像这样 -
def original_app(M1,M2):
N = M1.shape[0]
out = np.zeros(N)
for i in range(N):
out[i] = M1[i].dot(M2[:,i])
return out
Thus, for each iteration, we have :因此,对于每次迭代,我们有:
out[i] = M1[i].dot(M2[:,i])
Looking at the iterator, we need to align the first axis of M1
with the second axis of M2
.查看迭代器,我们需要将
M1
的第一个轴与M2
的第二个轴对齐。 Again, since we are performing matrix-multiplication
and that by its very definition is aligning the second axis of M1
with the first axis of M2
and also sum-reducing these elements at each iteration.同样,由于我们正在执行
matrix-multiplication
,并且根据其定义,将M1
的第二个轴与M2
的第一个轴对齐,并在每次迭代时对这些元素求和。
When porting over to einsum
, keep the axes to be aligned between the two inputs to have the same string when specifying the string notation to it.移植到
einsum
,在为其指定字符串表示法时,请保持轴在两个输入之间对齐以具有相同的字符串。 So, the inputs would be 'ij,ji
for M1
and M2
respectively.因此,
M1
和M2
分别为'ij,ji
。 The output after losing the second string from M1
, which is same as first string from M2
in that sum-reduction, should be left as i
.丢失来自
M1
的第二个字符串后的输出,与来自M2
第一个字符串相同的总和减少,应保留为i
。 Thus, the complete string notation would be : 'ij,ji->i'
and the final solution as : np.einsum('ij,ji->i',M1,M2)
.因此,完整的字符串符号将是:
'ij,ji->i'
,最终解决方案为: np.einsum('ij,ji->i',M1,M2)
。
Approach #2方法#2
The number of cols in M1
or number of rows in M2
is 2
. M1
的列数或M2
的行数为2
。 So, alternatively, we can just slice, perform the element-wise multiplication and sum up those, like so -因此,或者,我们可以只是切片,执行逐元素乘法并总结它们,就像这样 -
M1[:,0]*M2[0] + M1[:,1]*M2[1]
Runtime test运行时测试
In [431]: # Setup inputs
...: N = 1000
...: M1 = np.random.rand(N,2)
...: M2 = np.random.rand(2,N)
...:
In [432]: np.allclose(original_app(M1,M2),np.einsum('ij,ji->i',M1,M2))
Out[432]: True
In [433]: np.allclose(original_app(M1,M2),M1[:,0]*M2[0] + M1[:,1]*M2[1])
Out[433]: True
In [434]: %timeit original_app(M1,M2)
100 loops, best of 3: 2.09 ms per loop
In [435]: %timeit np.einsum('ij,ji->i',M1,M2)
100000 loops, best of 3: 13 µs per loop
In [436]: %timeit M1[:,0]*M2[0] + M1[:,1]*M2[1]
100000 loops, best of 3: 14.2 µs per loop
Massive speedup there!那里有大规模的加速!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.