1

I have 3 Numpy arrays, a, b and c. b and c are very large arrays and have the same length. Each element of b is 0, 1 or 2 and also the length of a is 3. Now I wonder if there is a way to eliminate the following for loop:

for i in range(len(b)):
    a[b[i]] += c[i]

Any comment would be greatly appreciated.

10
  • You want to eliminate the for loop and still have a modified that way? Commented Jan 4, 2017 at 16:11
  • yes, eliminating 'for' and have the same result Commented Jan 4, 2017 at 16:15
  • You have to iterate there is no other way, you can maybe merge 2 for loops so you only iterate once, but you cannot avoid it Commented Jan 4, 2017 at 16:17
  • Who talked about a ? I said if you have a for loop before that one you can try to put both treatment in the same loop. Show more code if you want help. Commented Jan 4, 2017 at 16:34
  • Give a small example so there's no ambiguity as what you expect. Commented Jan 4, 2017 at 16:40

2 Answers 2

3

NumPy ufuncs have an at method for cases like this:

numpy.add.at(a, b, c)

This does what everyone expects a[b] += c to do for an array b of indices before they see that it doesn't work.

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

1 Comment

Thank you very much. It helps me very much.
2

You can use np.bincount for such ID based summing, like so -

a += np.bincount(b,c,minlength=a.size)

Runtime test -

In [136]: # Large arrays as inputs
     ...: a = np.random.rand(3)
     ...: c = np.random.rand(10000)
     ...: b = np.random.randint(0,3,10000)
     ...: 
     ...: # Make copies for testing
     ...: a1 = a.copy()
     ...: a2 = a.copy()
     ...: 

In [137]: def bincount_app(a, b, c): # bincount approach as func
     ...:     a += np.bincount(b,c,minlength=a.size)
     ...:     

In [138]: %timeit np.add.at(a1, b, c) # @user2357112's soln
1000 loops, best of 3: 1.29 ms per loop

In [139]: %timeit bincount_app(a2, b, c)
10000 loops, best of 3: 36.6 µs per loop

1 Comment

Thank you very much. I really appreciate your time and help.

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.