Reputation: 17455
I have an array y
with indexes of values that must be incremented by one in another array x
just like x[y] += 1
, This is an example:
>>> x = np.zeros(5,dtype=np.int)
>>> y = np.array([1,4])
>>> x
array([0, 0, 0, 0, 0])
>>> x[y] += 1
>>> x
array([0, 1, 0, 0, 1])
So far so good, but then I've this problem:
>>> x
array([0, 1, 0, 0, 1])
>>> y = np.array([1,1])
>>> x
array([0, 1, 0, 0, 1])
>>> x[y] += 1
>>> x
array([0, 2, 0, 0, 1])
I was expecting x
to be array([0, 3, 0, 0, 1])
: x[1]
should be incremented by one twice,
but I got it with x[1]
incremented just by one.
How can I did it? Why is that happening?
Upvotes: 2
Views: 166
Reputation: 231385
x[y] += 1
is the equivalent to
x[y] = x[y] + 1
x[y]+1
# array([2, 2])
Effectively numpy
operates on the terms in parallel, not sequentially.
x[y]=[4,3] # or
x[y] += [4,3]
suggests that if different values are assigned to the same term, it is the last action that one has effect (but that probably isn't guaranteed).
np.add.at(x,y,1)
does what you expect.
from the documentation for np.add.at
:
For addition ufunc, this method is equivalent to
a[indices] += b
, except that results are accumulated for elements that are indexed more than once. For example,a[[0,0]] += 1
will only increment the first element once because of buffering, whereasadd.at(a, [0,0], 1)
will increment the first element twice.
Upvotes: 2
Reputation: 54330
Do this:
>>> x=np.array([0, 0, 0, 0, 0])
>>> y=np.array([1,4])
>>> x+=np.bincount(y, minlength=x.size)
>>> x
array([0, 1, 0, 0, 1])
>>> y=np.array([1,1])
>>> x+=np.bincount(y, minlength=x.size)
>>> x
array([0, 3, 0, 0, 1])
>>> map(id, x[y])
[20481944, 20481944]
x[1,1]
only references the same element, +1
therefore only act on one element.
Upvotes: 3