Reputation: 3
Suppose I have a 1D numpy array:
arr = np.arange(10)
Then I slice arr and assign to another variable:
arr2 = arr[5:8]
And I want to change arr :
arr2 *= 10
or:
arr2 = arr2 * 10
The results are different. Why are they different?
arr
array([ 0, 1, 2, 3, 4, 50, 60, 70, 8, 9])
arr
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
Upvotes: 0
Views: 401
Reputation: 231385
In [639]: arr = np.arange(10)
By indexing with a slice (basic indexing), arr2
is a view
of arr
. It shares the data buffer with arr
:
In [640]: arr2 = arr[5:8]
In [641]: arr2
Out[641]: array([5, 6, 7])
If we make a copy, values are copied, not shared:
In [642]: arr3 = arr[5:8].copy() # arr[[5,6,7]] is also a copy
By modifying arr2
in-place, we also modify part of arr
:
In [643]: arr2 *= 10
In [644]: arr2
Out[644]: array([50, 60, 70])
In [645]: arr
Out[645]: array([ 0, 1, 2, 3, 4, 50, 60, 70, 8, 9])
But not arr3
:
In [646]: arr3
Out[646]: array([5, 6, 7])
arr2 = arr2*10
does not modify the arr2
array, but rather assigns a whole new array to the arr2
variable.
So you need to understand what it means to assign an object to a variable. The difference between assign a variable, and modifying a mutable object. And the difference between array copy and view (and between basic and advanced indexing). This last one is specific to numpy
, the rest to Python as well.
Upvotes: 0
Reputation: 3130
In simplified terms, arr2 = arr[5:8]
assigns a reference to the 5:7
th elements of arr
to a variable arr2
.
Thus the operation arr2 *= 10
boils down to "multiply those elements by 10 in place", which modifies arr
in place (you are performing an in-place operation, a modification, on a reference, which therefore affects the original).
However, arr2 = arr2 * 10
says "take the result of multiplying the 5:7th elements by 10, then assign it to a variable called arr2
". Here, you perform an operation on a reference (not a modification), take the output (to be explicit, the operation arr2 * 10
returns a new object), and assign it to arr2
, which incidentally destroys the original reference (but this part is somewhat irrelevant).
Or compare these:
arr[5:8] *= 10
arr[5:8] = arr[5:8] * 10
arr2 = arr[5:8] * 10
The first two are equivalent. Your code is essentially a comparison between the first and the third (equivalently, the second and third). The second and third are not equal, because in your code, your earlier assignment of arr2 = arr[5:8]
has nothing to do with the LHS of arr2 = arr[5:8] * 10
.
Upvotes: 1