0

我有两个像

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]。我可以通过手动拆分数组和 for 循环来做到这一点。但是想知道是否有更 Pythonic 和 numpy 的方式来做到这一点?

4

3 回答 3

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])
于 2017-08-30T04:57:26.527 回答
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
于 2017-08-30T04:58:22.910 回答
1

您可以通过手动乘以和添加数组来执行点。如果您使用np.add'reduceat方法,您可以灵活地在完全任意的间隔上求和:

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

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

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

于 2017-08-30T05:09:24.803 回答