2012-03-20 4 views
11

Мой вопрос касается конкретной операции с массивом, которую я хочу выразить с помощью numpy.Numpy, накапливающий один массив в другом, используя индексный массив

У меня есть массив поплавки w и массив индексов idx той же длины, как w и я хочу подытожить все w с тем же значением idx и собирать их в массиве v. В цикле, это выглядит следующим образом:

for i, x in enumerate(w): 
    v[idx[i]] += x 

Есть ли способ сделать это с помощью операций с массивами? Моя догадка была v[idx] += w, но это не сработало, так как idx содержит тот же индекс несколько раз.

Спасибо!

+0

И * atomic * действительно является неприемлемым описанием того, что вы хотите сделать. – Constantinius

+0

Как вы бы описали? Надеюсь, что новый титул лучше. –

+1

@ Константин, Он принял ответ за все, кроме одного из вопросов, которые он задал, и у него был один ответ, который, в то время как хороший, не касался его реальной проблемы. Возможно, вы * должны работать над тем, чтобы не привлекать внимание к игровому аспекту этого сайта. –

ответ

15

numpy.bincount был введен для этой цели:

tmp = np.bincount(idx, w) 
v[:len(tmp)] += tmp 

Я думаю, как 1,6 вы можете также передать MINLENGTH в bincount.

+0

Я знал об этом, но я не знал, что это может справиться с весами! awesome :) –

+0

круто, почти забудь этого крошечного маленького эльфа. – nye17

+0

Пожалуйста, не стесняйтесь чувствовать себя моим героем до конца дня :) –

4

Это известное поведение и, хотя и несколько неудачное, не имеет обходного решения на уровне numpy. (bincount можно использовать для этого, если вы крутите руку). Выполнение цикла самостоятельно - это ваш лучший выбор.

Обратите внимание, что ваш код может быть немного более ясно, без повторного использования имени w и без введения другого набора индексов, как

for i, w_thing in zip(idx, w): 
    v[i] += w_thing 

Если вам нужно ускорить этот цикл, вы, возможно, спуститься к C. Cython делает это относительно легко.

+0

Упрощение: 'для i в idx: v [i] + = w [i]'. –

+1

Или отличная 'scipy.weave.inline'. – katrielalex

+0

Без индексов это должно работать, не так ли? Код, который вы разместили, просто '' v + w'', правильно? (Если '' v'' длиннее '' w'', используются только первые элементы '' len (w) '. Повторное использование' 'w'' было довольно плохой опечаткой, извините. –

Смежные вопросы