numpy截取的二维数组子数组会联动修改原数组,如何避免原数组被改动
切片联动修改原数组的核心原因
NumPy 做切片操作的时候,为了避免大数组切片时的内存拷贝开销,默认返回的不是独立的新数组,而是指向原数组内存块的视图——这个子数组没有自己的独立存储空间,只是记录了原数组的内存起始地址、步长信息,通过索引映射访问原数组对应位置的数据。
也就是说你修改x2_sub的元素,本质就是直接在原数组的内存地址上写值,两个数组共享同一块数据存储,自然会出现同步改动的情况,这是NumPy为了性能做的默认设计,不是代码bug。
实现子数组与原数组完全隔离的方法
只要在切片生成子数组的时候,主动给它分配独立的内存空间,生成不共享内存的副本,就能实现两者的修改完全互不干扰,常用方法有两种:
- 方法1:对切片结果调用
.copy()方法
这是开发中最常用的写法,语义明确,会在独立的内存区域新建一份切片数据的拷贝,和原数组彻底切断内存关联。示例代码:import numpy as np np.random.seed(0) x2 = np.random.randint(10, size=(3, 4)) # 切片后追加copy,生成独立副本 x2_sub = x2[:2, :2].copy() x2_sub[0, 0] = 99 print(x2_sub) # 运行输出: # [[99 0] # [ 7 9]] print(x2) # 运行输出(原数组不受任何修改影响): # [[5 0 3 3] # [7 9 3 5] # [2 4 7 6]] - 方法2:用
np.array()基于切片数据重建数组
把切片得到的视图作为入参传给np.array()构造函数,同样会生成独立存储的新数组,和.copy()的效果完全等价。写法示例:x2_sub = np.array(x2[:2, :2])
日常开发提醒:除了切片操作,NumPy 中像
reshape这类不改变数据总长度的形状变换,默认也会返回视图。只要你后续需要独立修改子数组、不希望污染原始数据,一定要主动生成副本,否则很容易出现隐蔽的内存数据串改问题。
内容的提问来源于stack exchange,提问作者zoldxk
相关产品推荐
相关产品推荐

