user7345804
user7345804

Reputation:

Why isn't array[:] copying the array?

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

Answers (1)

MSeifert
MSeifert

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

Related Questions