深拷贝和浅拷贝
深拷贝和浅拷贝
在操作数组的时候,它们的数据有时候拷贝进一个新的数组,有时候又不是。这经常是初学者感到困惑。下面有三种情况:
不拷贝:
如果只是简单的赋值,那么不会进行拷贝。示例代码如下:
a = np.arange(12)
b = a #这种情况不会进行拷贝
print(b is a) #返回True,说明b和a是相同的
View或者浅拷贝:
有些情况,会进行变量的拷贝,但是他们所指向的内存空间都是一样的,那么这种情况叫做浅拷贝,或者叫做View(视图)
。比如以下代码:
a = np.arange(12)
c = a.view()
print(c is a) #返回False,说明c和a是两个不同的变量
c[0] = 100
print(a[0]) #打印100,说明对c上的改变,会影响a上面的值,说明他们指向的内存空间还是一样的,这种叫做浅拷贝,或者说是view
# c 和 a在不同的栈区。如果通过c去修改堆区的值,因为a 和 c是指向一样的堆区,所以a的值也会发生改变
深拷贝:
将之前数据完完整整的拷贝一份放到另外一块内存空间中,这样就是两个完全不同的值了。示例代码如下:
a = np.arange(12)
d = a.copy()
print(d is a) #返回False,说明d和a是两个不同的变量
d[0] = 100
print(a[0]) #打印0,说明d和a指向的内存空间完全不同了。
例子:
像之前讲到的flatten
和ravel
就是这种情况,ravel
返回的就是View,而flatten
返回的就是深拷贝。
a1 = np.random.rand(2,4)
a1
Out
array([[0.20647272, 0.17443683, 0.81513683, 0.81169226],
[0.4805403 , 0.66732839, 0.34413928, 0.34445177]])
a2 = a1.ravel()
a2[0] = 0
a1 #修改了a1的值,说明ravel返回的是一个浅拷贝
Out
array([[0. , 0.17443683, 0.81513683, 0.81169226],
[0.4805403 , 0.66732839, 0.34413928, 0.34445177]])
a3 = a1.flatten()
a3[1] = 100
a3
Out
array([ 0. , 100. , 0.81513683, 0.81169226,
0.4805403 , 0.66732839, 0.34413928, 0.34445177])
总结:
在数组操作中分成三种拷贝:
1、不拷贝:直接赋值,那么栈区没有拷贝,只是用同一个栈区定义了不同的名称。
2、浅拷贝:只拷贝栈区,栈区指定的堆区并没有拷贝。
3、深拷贝:栈区和堆区都拷贝了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能