Reputation: 32524
In numpy subarrays obtained through any of slicing, masking or fancy indexing operations are just views to the original array, which can be demonstrated as follows:
$ python3
Python 3.5.2 (default, Nov 23 2017, 16:37:01)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy as np
>>> np.__version__
'1.11.0'
>>> a = np.arange(3); a[:2] = 111; a
array([111, 111, 2])
>>> a = np.arange(3); a[a<2] = 111; a
array([111, 111, 2])
>>> a = np.arange(3); a[[0,1]] = 111; a
array([111, 111, 2])
In the above example, the entire subarray was assigned to. However if we assign to an element of the subarray, the result of the slicing operation still behaves as a view, whereas the results of the masking and fancy indexing operations behave as independent copies:
>>> a = np.arange(3); a[:2][0] = 111; a
array([111, 1, 2])
>>> a = np.arange(3); a[a<2][0] = 111; a
array([0, 1, 2])
>>> a = np.arange(3); a[[0,1]][0] = 111; a
array([0, 1, 2])
Is this a bug in numpy, or is it by design? If it is by design, then what's the substantiation for such an inconsistency?
Upvotes: 3
Views: 483
Reputation: 107347
It's not a bug. As far as you pass a slice object to Numpy array the returned sub array is a view of the original items which means that even slice assignment or single item assignments will change the original array. But in other cases the returned result is not a view. It's, in fact, a shallow view (copy) of the chosen slice which only supports slice assignment like what other mutable objects in Python support.
It's also mentioned in documentation:
[...] As with index arrays, what is returned is a copy of the data, not a view as one gets with slices.
Upvotes: 2