Views and copies confusion with NumPy arrays when combining index operations

▼魔方 西西 提交于 2019-12-23 01:58:18

问题


>>> a = np.arange(12).reshape(3,4)

>>> a[0:3:2, :][:, [0,2]] = 100   ### the first time
>>> a  
array([[100, 1, 100, 3],
[ 4, 5, 6, 7],
[100, 9, 100, 11]])

>>> a[:, [0, 2]][0:3:2, :] = 0    ### second time
>>> a   
array([[100, 1, 100, 3],
       [ 4, 5, 6, 7],
       [100, 9, 100, 11]])

I am really confused about views and copies in python. The code above shows that the first time the given rows and columns in array a was changed to 100, which changed the original array a.

However, the second time the original array was not changed. Why is that?


回答1:


A lookup with [:, [0,2]] will return a copy because it's advanced indexing. However when you assign to a slice (e.g. array[whatever] = sth) it won't create the copy but assign to the specified items, even if it's advanced indexing.

So the first example works because the first slicing returns a view and then it uses assignment for the slice of the view.

However the second one "fails" because you assign to a slice of a copy (because the advanced indexing is done before the regular indexing).

The difference is mainly because another method is responsible for setting (__setitem__) to slices than for getting (__getitem__) these slices. To disassemble your statements:

a[0:3:2, :][:, [0,2]] = 100 

a.__getitem__((slice(0, 3, 2), slice(None))).__setitem__((slice(None), [0, 2]), 100)
|-------------- returns a view ------------|

while the second one would be:

a[:, [0,2]][0:3:2, :] = 0

a.__getitem__((slice(None), [0, 2])).__setitem__((slice(0, 3, 2), slice(None)), 0)
|--------- returns a copy ---------|


来源:https://stackoverflow.com/questions/46308370/views-and-copies-confusion-with-numpy-arrays-when-combining-index-operations

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!