tomerg
tomerg

Reputation: 363

Confusion about inability to assign numpy array element using multiple array indexing

I ran into a bug caused by using multiple sets of brackets to index an array, i.e. using a[i][j] (for various reasons, mostly laziness, which I've now fixed properly). While attempting to assign an element of the array, I found that I was unable to, but I didn't receive any kind of error to tell me why. I am confused as to why I can't do this:

>>> import numpy as np
>>> x = np.arange(0,50,10)
>>> idx = np.array([1,3,4])
>>> x[idx]
array([10, 30, 40])
>>> x[idx][1]
30
>>> x[idx][1] = 10    #this assignment doesn't work
>>> x[idx][1]
30

However, if I instead index the idx array inside the brackets, then it seems to work:

>>> x[idx[1]]
30
>>> x[idx[1]] = 100
>>> x[idx[1]]
100

Can someone explain to me why?

Upvotes: 1

Views: 135

Answers (2)

hpaulj
hpaulj

Reputation: 231385

Another way to explain this is that each [] translates into __getitem__() call, and each []= is a __setitem__ call.

x[idx][1]= 2

is then

x.__getitem__(idx).__setitem__(1, 2)

If x.__getitem__(idx) produces a new array with its own databuffer, the set changes that, not x. If on the other hand the get produces a view, then the change will appear in x.

It's important when working with arrays, that you understand the difference between a view and copy.

Upvotes: 2

juanpa.arrivillaga
juanpa.arrivillaga

Reputation: 95948

Because:

x[idx]

Creates a new array object with an independent, underlying buffer.

So then you index into that:

[1] = 10

Which does work, but then you don't keep that new array around, and it is discarded immediately.

Whereas:

x[idx[1]] = 100

Assigns to some particular index in the existing array object.

Upvotes: 2

Related Questions