结合索引操作时,会查看和复制NumPy数组的混乱情况 [英] Views and copies confusion with NumPy arrays when combining index operations
问题描述
>>> 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]])
我真的很困惑python中的视图和副本.上面的代码显示,数组a中的给定行和列第一次更改为100,这将更改原始数组a.
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?
推荐答案
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).
区别主要是因为另一种方法负责设置( __setitem__
),而不是获取( __getitem__
)这些切片.要反汇编您的声明:
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 ------------|
而第二个是:
a[:, [0,2]][0:3:2, :] = 0
a.__getitem__((slice(None), [0, 2])).__setitem__((slice(0, 3, 2), slice(None)), 0)
|--------- returns a copy ---------|
这篇关于结合索引操作时,会查看和复制NumPy数组的混乱情况的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!