Reputation: 363
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
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
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