子阵列的numpy dot积?

时间:2017-08-30 04:42:39

标签: numpy numpy-einsum

我有两个像ndarray一样的

n1 = np.array([1,2,3,4])
n2 = np.array([1,2,3,4])

虽然可以使用np.dot(n1, n2)轻松完成它们的点积,这样可以得到30作为正确的答案。如果我需要在n1和n2的两个子阵列上操作点,例如,

np.dot(np.array([1,2]), np.array([1,2]))  # first two elements from arrays
np.dot(np.array([3,4]), np.array([3,4]))  # last two elements

给出[5,25]。我可以手工拆分数组和循环。但是想知道是否有更多的pythonic和numpy方式来做到这一点?

3 个答案:

答案 0 :(得分:2)

这是一种方式:

In [124]: n1 = np.array([1,2,3,4])
     ...: n2 = np.array([1,2,3,4])
     ...: 

重新整形将数组拆分为所需的块:

In [125]: n1.reshape(2,2)
Out[125]: 
array([[1, 2],
       [3, 4]])

现在将所有元素相乘 - 并在右轴上求和(有时我猜是轴)。

In [126]: (n1.reshape(2,2)*n2.reshape(2,2)).sum(axis=1)
Out[126]: array([ 5, 25])

产品总数也可以用einsum表示 - 但如果语法太新,请不要担心:

In [127]: np.einsum('ij,ij->i',n1.reshape(2,2), n2.reshape(2,2))
Out[127]: array([ 5, 25])

答案 1 :(得分:2)

重塑为拥有两个两列的数组,因为我们需要每个长度为2的子数组,然后使用np.einsum进行总和减少 -

a = n1.reshape(-1,2)
b = n2.reshape(-1,2)

out = np.einsum('ij,ij->i',a,b)

另一个是进行逐元素乘法,然后使用一个整形,最后对每一行求和,以获得紧凑的解决方案 -

out = (n1*n2).reshape(-1,2).sum(1) # 2 is subarray length

答案 2 :(得分:1)

您可以通过手动相乘和添加数组来执行点。如果您使用np.addreduceat方法,则可以灵活地对任意间隔进行求和:

n = np.add.reduceat(n1 * n2, [0, 2])

如果你想得到前三个和最后一个元素的总和,你只需要传递[0, 3]索引(第二个参数)。

如果你对任意长度间隔不感兴趣,请改用其他答案。