Cae*_*ium 11 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]])
Run Code Online (Sandbox Code Playgroud)
但是,如果我第一次切片,然后切片行,它似乎是一个副本:
>>> a[:, [0, 2]][0:3:2, :] = 0
>>> a
array([[100, 1, 100, 3],
[ 4, 5, 6, 7],
[100, 9, 100, 11]])
Run Code Online (Sandbox Code Playgroud)
我很困惑,因为这两种方法最终会导致看似位置改变,但为什么第二种方法实际上不会改变数字?
Mal*_*ore 15
John Zwinck 接受的答案实际上是错误的(我只是以艰难的方式想通了这一点!)。问题中的问题是将“左值索引”与 numpy 的花哨索引结合起来。以下文档准确地解释了这种情况
https://scipy-cookbook.readthedocs.io/items/ViewsVsCopies.html
在“但是花哨的索引有时确实会返回视图,不是吗?”
Joh*_*nck 12
重要的是你是按行还是按列切片.按行切片可以返回视图,因为它是原始数组的连续段.按列切片必须返回副本,因为它不是连续的段.例如:
A1 A2 A3
B1 B2 B3
C1 C2 C3
Run Code Online (Sandbox Code Playgroud)
默认情况下,它以这种方式存储在内存中:
A1 A2 A3 B1 B2 B3 C1 C2 C3
Run Code Online (Sandbox Code Playgroud)
所以如果你想选择每一行,那就是:
[A1 A2 A3] B1 B2 B3 [C1 C2 C3]
Run Code Online (Sandbox Code Playgroud)
这可以描述为{start: 0, size: 3, stride: 6}
.
但是如果你想选择每一个第二列:
[A1] A2 [A3 B1] B2 [B3 C1] C2 [C3]
Run Code Online (Sandbox Code Playgroud)
并且无法使用单个开始,大小和步幅来描述.所以没有办法构建这样的视图.
如果您希望能够查看每个第二列而不是每隔一行,则可以使用列主要的Fortran命令构建数组:
np.array(a, order='F')
Run Code Online (Sandbox Code Playgroud)
然后它将被存储为:
A1 B1 C1 A2 B2 C2 A3 B3 C3
Run Code Online (Sandbox Code Playgroud)