You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NumPy数组索引赋值疑问:两种索引方式为何结果不同?

NumPy数组索引赋值的差异解析

先看你的代码执行结果:

import numpy as np

i = np.arange(2,4)
a = np.arange(5)
a[:][i] = 0  # 输出 [0 1 0 0 4]
print(a)

b = np.arange(5)
b[i][:] = 0  # 输出 [0 1 2 3 4]
print(b)

核心原因:切片索引 vs 数组索引的返回类型差异

NumPy里两种索引方式的返回结果本质不同:

  • 切片索引(arr[:]):返回原数组的视图(View),视图和原数组共享同一块内存空间,修改视图的元素会直接同步到原数组。
  • 数组索引(arr[i],i是整数数组):返回原数组的副本(Copy),副本是独立的内存块,修改副本不会影响原数组。

逐行拆解两个赋值操作

1. a[:][i] = 0的执行流程

  • 第一步a[:]:生成原数组a的视图,和a共享内存。
  • 第二步[i]:对这个视图进行数组索引,赋值操作会直接作用于视图对应的原数组内存位置,最终修改了原数组a。

2. b[i][:] = 0的执行流程

  • 第一步b[i]:对原数组b进行数组索引,返回的是b对应元素的独立副本,和原数组内存不共享。
  • 第二步[:]:对这个副本做切片赋值,修改的只是副本元素,原数组b的内存完全没被改动,所以输出还是初始值。

直观证明方法

用np.shares_memory()函数可以直接验证内存是否共享:

import numpy as np

i = np.arange(2,4)
a = np.arange(5)
a_slice = a[:]
print(np.shares_memory(a, a_slice))  # 输出 True,说明是视图

b = np.arange(5)
b_indexed = b[i]
print(np.shares_memory(b, b_indexed))  # 输出 False,说明是副本

也可以用id()辅助理解:id(a[:])和id(a)不同是因为视图是新的数组对象,但它的底层数据缓冲区和原数组共享;而b[i]的id()和b不同,且底层数据缓冲区完全独立,所以修改它不影响原数组。

内容的提问来源于stack exchange,提问作者Daniel Reese

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 15:52:32