Alvaro Fuentes
Alvaro Fuentes

Reputation: 17455

Numpy arrays assignment operations indexed with arrays

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

Answers (2)

hpaulj
hpaulj

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, whereas add.at(a, [0,0], 1) will increment the first element twice.

Upvotes: 2

CT Zhu
CT Zhu

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

Related Questions