繁体   English   中英

Numpy:通过切片查看与复制

[英]Numpy: views vs copy by slicing

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

第一的

首先是行切片,然后是列切片。 似乎是一种看法。

>>> 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]])

我很困惑,因为这两种方法最终会导致似乎位置发生变化,但为什么第二种实际上并没有改变数字?

John Zwinck 接受的答案实际上是错误的(我只是以艰难的方式想通了这一点!)。 问题中的问题是将“左值索引”与 numpy 的花哨索引结合起来。 以下文档准确地解释了这种情况

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

在“但是花哨的索引有时确实会返回视图,不是吗?”

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

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]

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

如果您希望能够查看每第二列而不是每第二行,您可以以列主要 aka Fortran 顺序构造数组:

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

然后它将被存储为:

A1 B1 C1 A2 B2 C2 A3 B3 C3

这是我的理解,供大家参考

a[0:3:2, :]                     # basic indexing, a view
... = a[0:3:2, :][:, [0, 2]]    # getitme version, a copy,
                                # because you use advanced
                                # indexing [:,[0,2]]
a[0:3:2, :][:, [0, 2]] = ...    # howver setitem version is
                                # like a view, setitem version
                                # is different from getitem version,
                                # this is not c++
a[:, [0, 2]]                    # getitem version, a copy,
                                # because you use advanced indexing
a[:, [0, 2]][0:3:2, :] = 0      # the copy is modied,
                                # but a keeps unchanged.

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM