Home > Software engineering >  Changing values in Numpy array according to index
Changing values in Numpy array according to index

Time:01-02

When I use the indices once to change the values, it works. However, when I use the indices twice to change the values, nothing has changed. Why I can't use the indices twice to change the values?

import numpy as np

a = np.arange(100)
a[np.array([10,20,30,40,50])] = 1

print(a[np.array([10,20,30,40,50])])

# array([1, 1, 1, 1, 1]) which can be modified as 1

a = np.arange(100)
(a[np.array([10,20,30,40,50])])[np.array([1,2,3])] = 1

print((a[np.array([10,20,30,40,50])])[np.array([1,2,3])])

# array([20, 30, 40]) which can not be modified as 1

CodePudding user response:

This is a confusing question about views and copies in NumPy. I found this question [Numpy: views vs copy by slicing] is similar to this one and this doc [Views versus copies in NumPy] mentioned by @Maltimore may explain.

NumPy Fancy Indexing returns a copy of numpy array instead of a view.
However, when set values to numpy array using fancy indexing, what python interpreter does is calling __setitem__ function. Take the code as an example.

In this line:

a[np.array([10,20,30,40,50])] = 1

What python actually does is

a.__setitem__(np.array([10,20,30,40,50]), 1)

i.e. there is not need to create neither a view or a copy because the method can be evaluated inplace (i.e. no new object creation is involved).

Break this line into the following code:

# (a[np.array([10,20,30,40,50])])[np.array([1,2,3])] = 1
a_copy = a[np.array([10,20,30,40,50])]
a_copy[np.array([1,2,3])] = 1

print(a[np.array([10,20,30,40,50])])
# [10, 20, 30, 40, 50]

print(a_copy)
# [10,  1,  1,  1, 50]

As a result, this line modifies the value of the copy, so the original numpy array is unchanged.

  • Related