如何明确指定最后一个索引 np.ufunc.reduceat

How to specify the last index explicitly to np.ufunc.reduceat

假设我有一个数组

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完全 知道有更好的方法可以做到这一点。这只是出于说明目的而设计的示例。这个问题的真正问题源于试图解决 .

我没怎么用过 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] 来说明发生了什么。