NumPy 数组的复制的几种实现方法

张开发
2026/4/16 3:51:15 15 分钟阅读

分享文章

NumPy 数组的复制的几种实现方法
在 NumPy 中操作数组时理解数据的复制机制是避免逻辑错误和内存浪费的关键。新手常因混淆 “复制” 与 “引用” 而踩坑本文将系统讲解三种场景无复制、视图浅复制和深复制。1 无复制No Copy at All简单赋值或函数传参时不会复制数组对象或其数据只是对同一对象的 “重命名” 或 “引用传递”。1.1 简单赋值同一对象的多个名称12345678importnumpy as np# 定义原始数组anp.array([[0,1,2,3],[4,5,6,7],[8,9,10,11]])ba# 无新对象创建b是a的“别名”print(bisa)# 输出 True证明是同一对象此时修改 b 会直接改变 a因为它们指向同一块内存。1.2 函数调用的引用传递Python 中可变对象如 NumPy 数组以引用方式传递给函数函数内的操作会影响原对象。2 视图 / 浅复制View or Shallow Copy视图会创建新的数组对象但共享原始数组的数据。新数组是原数据的 “窗口”数据本身未被复制。2.1 view方法创建视图1234ca.view()print(cisa)# 输出 Falsec是新对象print(c.baseisa)# 输出 Truec的底层数据由a持有print(c.flags.owndata)# 输出 Falsec不“拥有”自己的数据2.2 视图的 “形状独立数据共享”视图可以独立修改形状不影响原数组但修改数据会同步影响原数组。123456789cc.reshape((2,6))# 修改c的形状print(a.shape)# 原数组a形状仍为(3, 4)c[0,4]1234# 修改c的数据print(a)# 输出# array([[ 0, 1, 2, 3],# [1234, 5, 6, 7],# [ 8, 9, 10, 11]])2.3 数组切片返回视图对数组切片时返回的是原数组的视图而非新数组。1234567sa[:,1:3]# 切片得到视图ss[:]10# 修改视图的数据注意是s[:] 10不是s 10print(a)# 输出# array([[ 0, 10, 10, 3],# [1234, 10, 10, 7],# [ 8, 10, 10, 11]])注意s[:] 10 是修改视图数据而 s 10 是将 s 重新赋值为新对象不再关联原数组。3 深复制Deep Copy深复制会创建原数组及其数据的完整副本新数组拥有独立的内存空间与原数组完全解耦。3.1 copy方法创建深复制123da.copy()print(disa)# 输出 Falsed是新对象print(d.baseisa)# 输出 Falsed与a无任何共享3.2 深复制的数据独立性修改深复制的数组不会影响原数组。12d[0,0]9999print(a)# 原数组a不受影响输出与之前一致3.3 大数组切片的内存优化当原始数组很大且仅需要其一小部分时对切片进行深复制可释放原始数组的内存。123anp.arange(int(1e8))# 创建超大数组ba[:100].copy()# 对切片深复制b拥有独立数据dela# 可释放a占用的大量内存如果用 b a[:100]视图a 会被 b 引用即使 del a 也无法释放内存。4 总结三种方式对比类型是否创建新对象是否共享数据操作 / 方法数据修改影响无复制否是简单赋值、函数传参原数组与新变量相互影响视图浅复制是是view()、数组切片数据修改相互影响形状修改不影响原数组深复制是否copy()原数组与新数组完全独立掌握这三种机制能让你在处理 NumPy 数组时更精准地控制内存和数据一致性写出更健壮的代码。

更多文章