说我有一个数组
data = np.arange(6)
我想使用np.add.reduceat
找到整个数组和下半部分的和。 1
如果我这样做:
np.add.reduceat(data, [0, 6, 3])[::2]
我立即收到错误消息
IndexError: index 6 out-of-bounds in add.reduceat [0, 6)
如果我这样做
np.add.reduceat(data, [0, 5, 3])[::2]
我得到了错误的答案(10应该是15):
array([10, 12])
我唯一能想到的解决方案是掩盖需要最后一个索引的位置,从中减去1,然后在其中添加最后一个元素:
index = np.array([0, 6, 3])
mask = (index == data.size)
index[mask] -= 1
result = np.add.reduceat(data, index)
# Mask is shifted back by one because it's the previous element that needs to be updated
result[:-1][mask[1:]] += data[-1]
然后result[::2]
给出所需的答案。这看起来像是一场巨大的争夺,我希望这是一种优雅的单线(并且比这更快)。
1 我完全意识到有更好的方法可以做到这一点。为了说明的目的,这只是一个人为的例子。该问题的真正问题源于试图解决numpy: fast regularly-spaced average for large numbers of line segments / points的问题。
答案 0 :(得分:1)
我没怎么用reduceat
,但是看来您只能有一个开放式范围,一个add to the end
。
一种解决方法是填充数组(是的,我通常会反对使用np.append
:)):
In [165]: np.add.reduceat(np.append(x,0),[0,6,3])
Out[165]: array([15, 0, 12])
或具有完整范围的配对:
In [166]: np.add.reduceat(np.append(x,0),[0,6,3,6])
Out[166]: array([15, 0, 12, 0])
我省略了通常的[:: 2]来说明正在发生的事情。