3

In short I want to index into a matrix and add to each row.

In this example the first row (indexed by the 0) should get [1,1,1] added to it. Then the second row (indexed by the 1) should get [2, 2, 2] added to it. Finally the first row (indexed by the third 0) should get [3, 3, 3] added to it.

>>> a = np.array([np.array([1,2,3]), np.array([4,5,6])])
>>> a
array([[1, 2, 3],
       [4, 5, 6]])
>>> a[np.array([0,1,0]), :] += np.array([np.array([1,1,1]), np.array([2,2,2]), np.array([3,3,3])])

Desired:

>>> a
array([[5, 6, 7],
       [6, 7, 8]])

Actual:

>>> a
array([[4, 5, 6],
       [6, 7, 8]])

Edit 2:

As per comments below the solution runs slowly. From a portion of the code where I'm just adding 0 to test the speed:

print y.shape
print dW.shape
np.add.at(dW, (y, slice(None)), 0)

Yields:

(49000,)
(10, 3073)

And takes about 21 seconds. Without the np.add.at line the rest of the code takes about 1 second. y.npy dW.npy

3
  • 1
    could you verbally explain what your addition should mean? In fact, you're trying to replace row 0 twice in your assignment, so I think it's a bit hard to understand. Commented Jan 19, 2015 at 16:53
  • 1
    Done! let me know if I need to clarify further. Commented Jan 19, 2015 at 16:55
  • Document this well in your code. Otherwise it's a lurking bug/feature. Commented Jan 19, 2015 at 18:39

1 Answer 1

7

This is a known problem of numpy, explained well here:

For example, a[[0,0]] += 1 will only increment the first element once because of buffering, whereas add.at(a, [0,0], 1) will increment the first element twice.

numpy solves the problem using add.at(). Example:

a = array([1,2,3])
add.at(a,[0,0],4) # now a = array([9, 2, 3])

In this case we want this to work for a multidimensional array:

a = np.array([np.array([1,2,3]), np.array([4,5,6])])
np.add.at(a,([0,1,0],slice(None)),array([[1,1,1],[2,2,2],[3,3,3]]))

The result is:

array([[5, 6, 7], [6, 7, 8]])

I guess you mistyped a 7 for a 6.

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

6 Comments

Thanks! You got me unstuck!
Is there anyway to do this in a vectorized way?
this is the vectorized way
Hmm, I'm using this in an implementation and it's 5x slower than just using loops. It might be the slice(None) -- I'm still getting familiar with numpy, is that necessary?
This is interesting. Yes it could be because the operation is on a 2D array. And yes I think you really need the slice. Please post an example so that we can work on it.
|

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.