Python:Pandas对象的深浅拷贝
创始人
2025-05-31 00:08:19
0

这里仅以DataFrame为例进行说明。
Pandas版本:1.5.3

1 问题描述

  现有一DataFrame型变量A,现在需要对变量A做一些处理操作,但又希望保存A的一个原始副本。所以考虑将变量A赋值给变量B,然后再变量B上进行处理操作。但是处理完却发现A中的值也跟着发生了变动。具体举例如下:
在这里插入图片描述很显然,上述代码中虽然没有直接对A进行变换,但A的值还是发生了变化。这就涉及到了Python的深浅拷贝问题。本文主要关注Pandas对象的深浅拷贝,其他类型变量的深浅拷贝可以参考:https://blog.csdn.net/yeshang_lady/article/details/80755061

2 Pandas对象深浅拷贝

  Pandas中提供了copy()方法来对其对象进行拷贝,其内设的bool型参数deep可以设置是进行深拷贝。另外,copy标准库中deepcopy()方法也可以完成Pandas对象的深拷贝。这三者的区别如下:

  • deep=False:只对Pandas对象的数据和元素进行浅拷贝,即只复制数据和索引的引用,对副本变量的修改会影响原始数据。
  • deep=True:会对数据和索引进行复制。在副本变量上的修改不会影响原始变量。但这种复制不能递归(即当Pandas中的数据也是一个引用时,该方法不会对该引用的具体内容也进行复制)。
  • copy.deepcopy: 会对数据和索引进行复制,并且这种复制是可递归的。

2.1 对索引/列名的修改

  先创建对象A,并使用不同拷贝方法创建A的副本对象。先用id()方法来查看各个副本对象的列名/索引信息存放的位置是否相同。具体代码如下:

import pandas as pd
from copy import deepcopy
A=pd.DataFrame([['A',[3000,3002],22],['B',[3010,2900],29]],columns=['col_1','col_2','col_3'])
A_deep=A.copy(deep=True)
A_shallow=A.copy(deep=False)
A_copy=deepcopy(A)#查看各个对象的索引和列名的存放地址
print("对象A的索引存放地址:{},列名存放地址:{}".format(id(A.index),id(A.columns)))
print("对象A_deep的索引存放地址:{},列名存放地址:{}".format(id(A_deep.index),id(A_deep.columns)))
print("对象A_shallow的索引存放地址:{},列名存放地址:{}".format(id(A_shallow.index),id(A_shallow.columns)))
print("对象A_copy的索引存放地址:{},列名存放地址:{}".format(id(A_copy.index),id(A_copy.columns)))

其结果如下:
在这里插入图片描述
从图上可以看出,浅拷贝得到的对象A_shallow的索引和列名存放地址与原始变量A的存放地址相同。而其他两种方法得到的存放地址与原始变量A不同。但由于DataFrame型变量的索引和列名都是不可变对象,所以对A_shallow中的列名或索引的修改不会导致原始变量A的改变。具体如下:

#A_shallow.columns[0]='A1' 无法运行,提示其为不可变类型
A_shallow.columns=['A1','B1','C1'] #这种写法相当于将A_shallow的列名指向内存中另外一个地址
print("修改后的A_shallow的列名:",list(A_shallow.columns))
print("修改A_shallow的列名后A的列名:",list(A.columns))
print("修改后的A_shallow的列名存放地址:",id(A_shallow.columns))

其结果如下:
在这里插入图片描述
从图中可以看到,A_shallow的列名改名并没有导致A跟着变动。(修改索引也是)

2.2 数据修改

  • 第1种情况:浅拷贝(deep=False)。具体如下:
import pandas as pd
from copy import deepcopy
A=pd.DataFrame([['A',[3000,3002],22],['B',[3010,2900],29]],columns=['col_1','col_2','col_3'])
A_shallow=A.copy(deep=False)
A_shallow.loc[0,'col_1']='C'
A_shallow['col_3']=[34,27]

A_shallow和A的值如下:
在这里插入图片描述
从结果上可以看到奇怪的现象,就是对A_shallow中col_3整列的修改并没有影响到A中的相应列,好似与浅拷贝的定义不符合。这是因为A_shallow中的col_3指向了新的内存地址,而A中col_3列指向的位置不变。这与下述代码同义:

a=[1,2]
print(a,id(a))
a[0]=0
print(a,id(a))
a=[2,3,5]
print(a,id(a))

其结果如下:
在这里插入图片描述

  • 第2种情况:深拷贝(deep=True)。具体如下:
import pandas as pd
from copy import deepcopy
A=pd.DataFrame([['A',[3000,3002],4002],['B',[3010,2900],3009]],columns=['col_1','col_2','col_3'])
A_deep=A.copy(deep=True)
A_deep.loc[0,'col_1']='C'
A_deep.loc[0,'col_2'][0]=3
A_deep.loc[1,'col_2']=[2020]

其结果如下:
在这里插入图片描述

  • 第3种情况:deepcopy()方法。具体如下:
import pandas as pd
from copy import deepcopy
A=pd.DataFrame([['A',[3000,3002],4002],['B',[3010,2900],3009]],columns=['col_1','col_2','col_3'])
A_copy=deepcopy(A)
A_copy['col_2']=[[2002,2012],[3030,2020]]
A_copy.loc[0,'col_1']='E'

其结果如下:
在这里插入图片描述

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...