>>> a = np.arange(12).reshape(3,4)
>>> a[0:3:2, :][:, [0,2]] = 100 ### the first time
>>> a
array([[100, 1, 100, 3],
[ 4, 5, 6, 7],
[100, 9, 100, 11]])
>>> a[:, [0, 2]][0:3:2, :] = 0 ### second time
>>> a
array([[100, 1, 100, 3],
[ 4, 5, 6, 7],
[100, 9, 100, 11]])
I am really confused about views and copies in python. The code above shows that the first time the given rows and columns in array a was changed to 100, which changed the original array a.
However, the second time the original array was not changed. Why is that?
A lookup with [:, [0,2]]
will return a copy because it's advanced indexing. However when you assign to a slice (e.g. array[whatever] = sth
) it won't create the copy but assign to the specified items, even if it's advanced indexing.
So the first example works because the first slicing returns a view and then it uses assignment for the slice of the view.
However the second one "fails" because you assign to a slice of a copy (because the advanced indexing is done before the regular indexing).
The difference is mainly because another method is responsible for setting (__setitem__
) to slices than for getting (__getitem__
) these slices. To disassemble your statements:
a[0:3:2, :][:, [0,2]] = 100
a.__getitem__((slice(0, 3, 2), slice(None))).__setitem__((slice(None), [0, 2]), 100)
|-------------- returns a view ------------|
while the second one would be:
a[:, [0,2]][0:3:2, :] = 0
a.__getitem__((slice(None), [0, 2])).__setitem__((slice(0, 3, 2), slice(None)), 0)
|--------- returns a copy ---------|
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With