Reputation:
I recently found a solution to a problem I find bizarre and would like to better understand the situation. The problem involves over-writing values at specified indices of an array.
import numpy as np
# create array to overwrite
mask = np.ones(10)
# first set of index-value pairs
idx_1 = [0, 3, 4]
val_1 = [100, 200, 300]
# second set of index-value pairs
idx_2 = [1, 5, 6]
val_2 = [250, 505, 650]
# third set of index-value pairs
idx_3 = [7, 8, 9]
val_3 = [900, 800, 700]
def overwrite_mask(mask, indices, values):
""" This function overwrites elements in mask with values at indices. """
mask[indices] = values
return mask
# incorrect
# res_1 = overwrite_mask(mask[:], idx_1, val_1)
# res_2 = overwrite_mask(mask[:], idx_2, val_2)
# res_3 = overwrite_mask(mask[:], idx_3, val_3)
# >> [ 100. 250. 1. 200. 300. 505. 650. 900. 800. 700.]
# >> [ 100. 250. 1. 200. 300. 505. 650. 900. 800. 700.]
# >> [ 100. 250. 1. 200. 300. 505. 650. 900. 800. 700.]
# correct
res_1 = overwrite_mask(mask.copy(), idx_1, val_1)
res_2 = overwrite_mask(mask.copy(), idx_2, val_2)
res_3 = overwrite_mask(mask.copy(), idx_3, val_3)
# [ 100. 1. 1. 200. 300. 1. 1. 1. 1. 1.]
# [ 1. 250. 1. 1. 1. 505. 650. 1. 1. 1.]
# [ 1. 1. 1. 1. 1. 1. 1. 900. 800. 700.]
I was under the impression that [:]
applied after an array produced an exact copy of the array. But it seems as though [:]
isn't working as it should in this context.
What is happening here?
Upvotes: 1
Views: 58
Reputation: 152667
I was under the impression that
[:]
applied after an array produced an exact copy of the array.
That's wrong. The [:]
applied to instances of Python types like list
, str
, ... will return a "shallow" copy but that doesn't mean the same applies to NumPy arrays.
In fact NumPy will always return views when "basic slicing" is used. Because [:]
is basic slicing it will never copy the array. See the documentation:
All arrays generated by basic slicing are always views of the original array.
Upvotes: 3