子数组的 numpy 点积?
numpy dot product of sub array?
我有两个类似的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]。我可以通过手动拆分数组和 for 循环来完成。但是想知道是否有更多 pythonic 和 numpy 的方法来做到这一点?
这是一种方法:
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])
重塑为两个两列数组,因为我们想要每个长度为 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
您可以通过手动对数组进行乘法和加法来执行点运算。如果您使用 np.add
's reduceat
方法,您可以灵活地对完全任意的区间求和:
n = np.add.reduceat(n1 * n2, [0, 2])
如果你想得到前三个和最后一个元素的总和,你只需为索引(第二个参数)传递 [0, 3]
。
如果您对任意长度的间隔不感兴趣,请改用其他答案。
我有两个类似的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]。我可以通过手动拆分数组和 for 循环来完成。但是想知道是否有更多 pythonic 和 numpy 的方法来做到这一点?
这是一种方法:
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])
重塑为两个两列数组,因为我们想要每个长度为 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
您可以通过手动对数组进行乘法和加法来执行点运算。如果您使用 np.add
's reduceat
方法,您可以灵活地对完全任意的区间求和:
n = np.add.reduceat(n1 * n2, [0, 2])
如果你想得到前三个和最后一个元素的总和,你只需为索引(第二个参数)传递 [0, 3]
。
如果您对任意长度的间隔不感兴趣,请改用其他答案。