如何深度拷贝含Python对象的Pandas DataFrame避免相互影响?
解决Pandas DataFrame嵌套列表的深度拷贝问题
当使用copy.deepcopy()或Pandas自带的df.copy(deep=True)拷贝包含嵌套列表的DataFrame时,修改原DataFrame中的列表元素会波及拷贝后的对象——这是因为Pandas的深拷贝不会递归处理单元格内的可变嵌套对象(比如列表),导致原对象和拷贝对象共享同一个列表引用。
以下是几种实现真正深度拷贝的方案,确保拷贝后的tmp不受原DataFrame修改影响:
方法1:对每个单元格单独做深度拷贝
使用applymap()遍历DataFrame的每个单元格,对每个对象执行copy.deepcopy(),彻底切断嵌套对象的引用关联:
import pandas as pd import copy # 构造示例DataFrame df = pd.DataFrame({ 'species': [['cat'], ['dog'], ['cat', 'dog']], 'count': [1, 2, 3] }) # 执行真正的深度拷贝 tmp = df.applymap(copy.deepcopy) # 修改原DataFrame的嵌套列表 df.loc[2, 'species'].append('bird') # 验证结果 print(df.loc[2, 'species']) # 输出: ['cat', 'dog', 'bird'] print(tmp.loc[2, 'species']) # 输出: ['cat', 'dog']
方法2:通过字典序列化重新构造DataFrame
将原DataFrame转为字典后重新构造新的DataFrame,序列化过程会自动创建嵌套对象的新实例:
tmp = pd.DataFrame(df.to_dict(orient='records'))
此方法操作简洁,但对于大型DataFrame,效率略低于方法1。
方法3:单独处理含嵌套对象的列
如果只有部分列包含嵌套列表,可先做DataFrame深拷贝,再对目标列单独执行深度拷贝,提升效率:
tmp = df.copy(deep=True) # 仅对包含嵌套列表的列做深度拷贝 tmp['species'] = tmp['species'].apply(copy.deepcopy)
关键注意点
Pandas自带的df.copy(deep=True)和标准库的copy.deepcopy()仅会拷贝DataFrame的顶层结构,不会递归处理单元格内的可变嵌套对象(如列表、字典),因此必须针对这些嵌套对象额外执行深度拷贝操作。
内容的提问来源于stack exchange,提问作者Olivier Maxwell
相关产品推荐
相关产品推荐

