Reputation: 57
import numpy as np
a = np.array([[0, 1, 2],
[0, 1, 2],
[1, 1, 2]])
a[[0, 1]] = 100 # Changed
print(a)
a[[0, 1]][0, 0] = 98 # Not Changed
print(a)
a[0:2][0, 0] = 99 # Changed
print(a)
the output is :
# first
[[100 100 100]
[100 100 100]
[ 1 1 2]]
# second
[[100 100 100]
[100 100 100]
[ 1 1 2]]
# third
[[ 99 100 100]
[100 100 100]
[ 1 1 2]]
so why the second way didn't change the a array, and the first way and third way worked? I had googled many answers,but I still not understand.
Upvotes: 3
Views: 56
Reputation: 1552
It's complicated.
Basically, you are doing advanced indexing in case 1 and 2, and basic indexing in case 3. The NumPy docs on advanced indexing state:
Advanced indexing always returns a copy of the data (contrast with basic slicing that returns a view).
So we already know the difference between case 2 and 3. Case 2 is basically equivalent to
b = a[[0, 1]]
b[0, 0] = 98
Since advanced indexing creates a copy, b
is not linked to a
anymore, and changes are not reflected. In case 3, we have
b = a[0:2]
b[0, 0] = 99
where b
is now a view into a
(basic indexing), so changes in b
are reflected in a
.
The essential difference is that you cannot split this up into an assignment b = ...
and subsequent setitem
operation. Instead, you are doing setitem
directly on the result on the indexing, which does not create a copy (only getitem
operates on copies). So we get the same behavior as in case 2.
The following illustrates this:
Case 1 is equivalent to
setitem(a, [0, 1], 100) # operates directly on a
Case 2 is equivalent to
setitem(
getitem(a, [0, 1]), # this is a copy
[0, 0],
98
)
Upvotes: 6