Увеличение массива Numpy с повторными индексами - PullRequest
15 голосов
/ 05 января 2010

У меня есть массив Numpy и список индексов, значения которых я бы хотел увеличить на единицу. Этот список может содержать повторяющиеся индексы, и я хотел бы, чтобы приращение масштабировалось с количеством повторений каждого индекса. Без повторов команда проста:

a=np.zeros(6).astype('int')
b=[3,2,5]
a[b]+=1

С повторениями я придумала следующий метод.

b=[3,2,5,2]                     # indices to increment by one each replicate
bbins=np.bincount(b)
b.sort()                        # sort b because bincount is sorted
incr=bbins[np.nonzero(bbins)]   # create increment array
bu=np.unique(b)                 # sorted, unique indices (len(bu)=len(incr))
a[bu]+=incr

Это лучший способ? Есть ли риск, связанный с предположением, что операции np.bincount и np.unique приведут к одному и тому же отсортированному порядку? Мне не хватает какой-нибудь простой операции Numpy, чтобы решить эту проблему?

Ответы [ 4 ]

17 голосов
/ 06 марта 2015

В numpy> = 1.8 вы также можете использовать метод at с добавлением «универсальной функции» («ufunc»). Как примечание документов :

Для сложения ufunc этот метод эквивалентен a [indexes] + = b, за исключением того, что результаты накапливаются для элементов, которые проиндексированы более одного раза.

Итак, взяв ваш пример:

a = np.zeros(6).astype('int')
b = [3, 2, 5, 2]

... до того ...

np.add.at(a, b, 1)

… оставит a как…

array([0, 0, 2, 1, 0, 1])
5 голосов
/ 05 января 2010

После того, как вы сделаете

bbins=np.bincount(b)

почему бы не сделать:

a[:len(bbins)] += bbins

(отредактировано для дальнейшего упрощения.)

1 голос
/ 09 января 2010

Если b является небольшим поддиапазоном a, можно уточнить ответ Алока следующим образом:

import numpy as np
a = np.zeros( 100000, int )
b = np.array( [99999, 99997, 99999] )

blo, bhi = b.min(), b.max()
bbins = np.bincount( b - blo )
a[blo:bhi+1] += bbins

print a[blo:bhi+1]  # 1 0 2
0 голосов
/ 05 января 2010

Почему бы и нет?

for i in b:
    a[i] += 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...