Как указать последний индекс явно для np.ufunc.reduceat - PullRequest
0 голосов
/ 13 сентября 2018

Скажем, у меня есть массив

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: быстрое регулярное среднее значение для большого количества отрезков / точек .

1 Ответ

0 голосов
/ 13 сентября 2018

Я не использовал 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], чтобы прояснить, что происходит.

...