Numpy:通过切片查看vs复制

时间:2017-11-08 13:33:26

标签: python numpy slice

当我进行切片时,发生了意想不到的事情,这似乎是第一个被视图,但第二个是复制。

第一

第一片行,然后是片段。这似乎是一种观点。

>>> a = np.arange(12).reshape(3, 4)   
>>> a[0:3:2, :][:, [0, 2]] = 100
>>> a
array([[100,   1, 100,   3],
       [  4,   5,   6,   7],
       [100,   9, 100,  11]])

第二

但是,如果我第一次切片,然后切片行,它似乎是一个副本:

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

我很困惑,因为这两种方法最终会导致看似位置改变,但为什么第二种方法实际上不会改变数字呢?

3 个答案:

答案 0 :(得分:9)

重要的是你是按行还是按列切片。按行切片可以返回视图,因为它是原始数组的连续段。按列切片必须返回副本,因为它不是连续的段。例如:

A1 A2 A3
B1 B2 B3
C1 C2 C3

默认情况下,它以这种方式存储在内存中:

A1 A2 A3 B1 B2 B3 C1 C2 C3

因此,如果你想选择每一行,那就是:

[A1 A2 A3] B1 B2 B3 [C1 C2 C3]

可以将其描述为{start: 0, size: 3, stride: 6}

但是如果你想选择每一个第二列:

[A1] A2 [A3 B1] B2 [B3 C1] C2 [C3]

并且无法使用单个开始,大小和步幅来描述。所以没有办法构建这样的观点。

如果您希望能够查看每个第二列而不是每隔一行,您可以使用列主要的Fortran命令来构建数组:

np.array(a, order='F')

然后它将被存储:

A1 B1 C1 A2 B2 C2 A3 B3 C3

答案 1 :(得分:1)

John Zwinck接受的答案实际上是错误的(我只是很难理解这一点!)。 问题是将“左值索引”与numpy的奇特索引结合在一起。 以下文档准确说明了这种情况

https://scipy-cookbook.readthedocs.io/items/ViewsVsCopies.html

“但是,花式索引有时似乎会返回视图,不是吗?”

答案 2 :(得分:0)

这是我的理解,供您参考

.ngx-gallery-image:first-of-type .fa-star { color:#fc0; }

如果我有任何误解,请指出。