11

My question is about a specific array operation that I want to express using numpy.

I have an array of floats w and an array of indices idx of the same length as w and I want to sum up all w with the same idx value and collect them in an array v. As a loop, this looks like this:

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

Is there a way to do this with array operations? My guess was v[idx] += w but that does not work, since idx contains the same index multiple times.

Thanks!

9
  • And atomic really is an inappropriate description for what you want to do. Commented Mar 20, 2012 at 16:06
  • How would you describe it? Hope new title is better. Commented Mar 20, 2012 at 16:08
  • 1
    @Constantinius, He accepted an answer for all but one of the questions he asked, which had one response which, while good, did not address his actual problem. Perhaps you should work on not drawing attention to the game aspect of this site. Commented Mar 20, 2012 at 16:12
  • I like the new description, much better. Atomic is often referred to in context of multi-threaded programming, so the question title was misleading. Commented Mar 20, 2012 at 16:12
  • @MikeGraham I accepted some good answers as response to his comment. Commented Mar 20, 2012 at 16:13

2 Answers 2

15

numpy.bincount was introduced for this purpose:

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

I think as of 1.6 you can also pass a minlength to bincount.

Sign up to request clarification or add additional context in comments.

2 Comments

I was aware of bincount but I didn'know it could handle weights! awesome :)
Please feel free to feel as my hero for the rest of the day :)
4

This is a known behavior and, though somewhat unfortunate, does not have a numpy-level workaround. (bincount can be used for this if you twist its arm.) Doing the loop yourself is really your best bet.

Note that your code might have been a bit more clear without re-using the name w and without introducing another set of indices, like

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

If you need to speed up this loop, you might have to drop down to C. Cython makes this relatively easy.

4 Comments

Simpler still: for i in idx: v[i] += w[i].
Without indices this should work, right? The code you posted simply does v + w, right? (If v is longer than w only the first len(w) elements are used. Reusing w was an pretty bad typo, sorry.
@AndreasMueller, Sorry, I had a typo.
@larsmans, There was a typo in my code snippet which I have fixed. That code does not do the same thing as OP's code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.