4

Given numpy ndarray A and an integer array I, of the same shape, with highest value imax and an array B = np.zeros(imax) we can do B[I] = A. However if I has repeated entries the last assignment holds. I need to do this while summing over repeated entries instead, like

For i in range(A.size):
    B[I.ravel()[i]] += A.ravel()[i]

Is there a good way to do this in numpy?

For example, I want this behavior (but neither = nor += works like this)

A = np.array((1,2,5,9))
I = np.array((0,1,2,0),dtype=int)
B = np.zeros(3)
B[I] += A
print(B)
>>> array([10,2,5])

Here we see 1+9=10 in the first entry.

4
  • 1
    Your question would become clearer (and easier to answer correctly), if you provided an example of data that demonstrates the problem. Commented Mar 2, 2020 at 1:56
  • 2
    add.at provides an un-buffered addition for use when you have index duplicates Commented Mar 2, 2020 at 4:30
  • @Grismar I added an example! Commented Mar 2, 2020 at 12:05
  • @hpaulj That is the answer, thanks a lot! If you want to make it an answer I will accept it. Commented Mar 2, 2020 at 12:09

1 Answer 1

6
In [1]: A = np.array((1,2,5,9)) 
   ...: I = np.array((0,1,2,0),dtype=int) 
   ...: B = np.zeros(3) 
   ...: B[I] += A                                                                                                          
In [2]: B                                                                                                                  
Out[2]: array([9., 2., 5.])

This a buffered solution, different from an iterative one:

In [3]: B = np.zeros(3)                                                                                                    
In [4]: for i,a in zip(I,A): 
   ...:     B[i] += a 
   ...:                                                                                                                    
In [5]: B                                                                                                                  
Out[5]: array([10.,  2.,  5.])

The unbuffered solution using the ufunc.at:

In [6]: B = np.zeros(3)                                                                                                    
In [7]: np.add.at(B, I, A)                                                                                                 
In [8]: B                                                                                                                  
Out[8]: array([10.,  2.,  5.])
Sign up to request clarification or add additional context in comments.

Comments

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.