NumPy混合基础索引与高级索引时返回视图还是副本?
NumPy混合基础索引与高级索引时返回视图还是副本?
这个问题确实是NumPy里容易让人懵的细节,我结合你的例子给你拆解清楚~
先看你给出的第一个代码示例:
import numpy as np x = np.arange(25).reshape(5, 5) print(x.base) y = x[:2, [0, 2]] print(y.base)
它的输出是:
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24] [[0 5] [2 7]]
这里y是一个视图,但它的base不是原数组x的base,而是基于x[:2](前两行的切片视图)生成的新视图。原因在于:当你在最后一个维度使用高级索引(整数数组),前面的维度用基础切片索引时,NumPy可以基于前面的连续切片,通过调整列的访问步长来生成新视图——不过这个视图的内存不是连续的,所以它的base指向的是切片后的中间视图,而非原数组。
再看你第二个例子:
>>> import numpy as np >>> x = np.arange(25).reshape(5, 5) >>> x[:2, [0,2]].base array([[0, 5], [2, 7]]) >>> x[[0,2], :2].base >>>
这里x[[0,2], :2].base返回None,说明它是一个副本。这是因为你在第一个维度使用了高级索引(整数数组),后面的维度用切片。这种情况下,选中的行在原数组中是不连续的(第0行和第2行),NumPy无法通过单一的连续内存块或统一步长来描述结果,只能创建一个新的数组副本,因此base为None。
那怎么提前预测混合索引会返回视图还是副本?核心规则可以总结这几点:
- 如果高级索引仅出现在最后一个维度,前面的维度都是基础切片索引,结果大概率是视图(但视图的
base可能是中间切片,而非原数组) - 如果高级索引出现在前面的维度,或者同时在多个维度使用高级索引,结果几乎都是副本
- 本质判断标准:看结果的元素在原数组内存中是否能通过「连续内存块 + 统一步长」来遍历。如果可以,返回视图;如果元素在原内存中分散排布、无法用单一步长描述,就返回副本。
备注:内容来源于stack exchange,提问作者Antonios Sarikas
相关产品推荐
相关产品推荐

