array1的第i行和array2的第i列的计算乘积-NumPy [英] Computing product of ith row of array1 and ith column of array2 - NumPy

查看:214
本文介绍了array1的第i行和array2的第i列的计算乘积-NumPy的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个形状为(N*2)的矩阵M1和另一个矩阵M2 (2*N),我想获得一个(N)的结果,每个元素i是第i行的乘积M2M1i列中的第一个. 我尝试在NumPy中使用点,但是它只能给我矩阵乘法结果,即(N*N),当然,我可以取对角线,这是我想要的,我想知道是否有更好的方法可以这样吗?

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 ith row of M1 and ith column of 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?

推荐答案

方法1

您可以使用 np.einsum -

You can use np.einsum -

np.einsum('ij,ji->i',M1,M2)

说明:

原始的循环解决方案看起来像这样-

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])

看一下迭代器,我们需要将M1的第一个轴与M2的第二个轴对齐.同样,由于我们正在执行matrix-multiplication,并且按照其定义,就是将M1的第二个轴与M2的第一个轴对齐,并且在每次迭代时也将这些元素求和.

Looking at the iterator, we need to align the first axis of M1 with the second axis of 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.

移植到einsum时,在为其指定字符串符号时,应使两个输入之间要对齐的轴具有相同的字符串.因此,对于M1M2,输入分别为'ij,ji.丢失M1中的第二个字符串后的输出(与该和中的M2中的第一个字符串相同)应保留为i.因此,完整的字符串符号为:'ij,ji->i',最终解决方案为:np.einsum('ij,ji->i',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. So, the inputs would be 'ij,ji for M1 and M2 respectively. 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. Thus, the complete string notation would be : 'ij,ji->i' and the final solution as : np.einsum('ij,ji->i',M1,M2).

方法2

M1中的列数或M2中的行数是2.因此,或者,我们可以像这样对切片,执行逐元素乘法并将其求和,-

The number of cols in M1 or number of rows in M2 is 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]


运行时测试

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

大量加速!

这篇关于array1的第i行和array2的第i列的计算乘积-NumPy的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆