You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas深拷贝嵌套列仍影响原DataFrame?求独立修改方案

Pandas中deep=True复制后修改嵌套列仍影响原DataFrame的问题及解决方法

问题说明

使用df.copy(deep=True)复制包含嵌套字典/列表的DataFrame时,修改副本的嵌套列字段值会同步影响原DataFrame。即使不是重命名字段,仅修改嵌套字段的数值,原DataFrame的对应数据也会被改变。

示例代码及现象:

import pandas as pd

df = pd.DataFrame({'a': [{'field': [1,2,3.0]}, {'field': [1,2,4.0]}, {'field': [1,2,5.0]}]})
print('原DataFrame: \n', df['a'])

def integer_converter(x):
    x['a']['field'] = [int(i) for i in x['a']['field']]

df2 = df.copy(deep=True)
df2.apply(integer_converter, axis=1)
print('修改后的df2: \n', df2['a'])
print('再次打印原DataFrame: \n', df['a'])

输出结果显示:原df的嵌套数组也被转为整数类型,说明副本和原DataFrame的嵌套数据仍共享内存。

原因分析

Pandas的deep=True复制仅对DataFrame的顶层结构做深度复制,但对于嵌套的Python可变对象(如字典、列表),只会复制对象的引用而非对象本身。也就是说,嵌套的字典/列表依然和原DataFrame共享内存空间,修改副本里的嵌套对象时,原对象会同步被修改。

解决方案

方法1:手动对嵌套对象做深度复制

使用Python标准库的copy.deepcopy()对嵌套列的每个元素单独做深度复制,彻底切断与原数据的引用关联:

import pandas as pd
import copy

df = pd.DataFrame({'a': [{'field': [1,2,3.0]}, {'field': [1,2,4.0]}, {'field': [1,2,5.0]}]})
print('原DataFrame: \n', df['a'])

# 先复制DataFrame,再对嵌套列做深度复制
df2 = df.copy()
df2['a'] = df2['a'].apply(copy.deepcopy)

def integer_converter(x):
    x['a']['field'] = [int(i) for i in x['a']['field']]

df2.apply(integer_converter, axis=1)
print('修改后的df2: \n', df2['a'])
print('再次打印原DataFrame: \n', df['a'])

方法2:修改时创建新的嵌套对象

在处理数据时,不直接修改原嵌套对象的引用,而是创建新的字典/列表替换原有值:

import pandas as pd

df = pd.DataFrame({'a': [{'field': [1,2,3.0]}, {'field': [1,2,4.0]}, {'field': [1,2,5.0]}]})
print('原DataFrame: \n', df['a'])

def integer_converter(x):
    # 创建新字典,避免修改原引用
    new_nested = x['a'].copy()
    new_nested['field'] = [int(i) for i in new_nested['field']]
    return new_nested

df2 = df.copy(deep=True)
df2['a'] = df2.apply(integer_converter, axis=1)
print('修改后的df2: \n', df2['a'])
print('再次打印原DataFrame: \n', df['a'])

方法3:展开嵌套结构后复制(适用于规则嵌套)

将嵌套数据展开为扁平DataFrame,复制后再还原嵌套结构,彻底隔离数据:

import pandas as pd

df = pd.DataFrame({'a': [{'field': [1,2,3.0]}, {'field': [1,2,4.0]}, {'field': [1,2,5.0]}]})
print('原DataFrame: \n', df['a'])

# 展开嵌套结构为扁平表
df_flat = pd.json_normalize(df['a'], record_prefix='a.')
df2_flat = df_flat.copy(deep=True)

# 修改数据
df2_flat['a.field'] = df2_flat['a.field'].apply(lambda x: [int(i) for i in x])

# 还原嵌套结构
df2 = pd.DataFrame({'a': df2_flat.to_dict('records')})
df2['a'] = df2['a'].apply(lambda x: {k.replace('a.', ''): v for k, v in x.items()})

print('修改后的df2: \n', df2['a'])
print('再次打印原DataFrame: \n', df['a'])

内容的提问来源于stack exchange,提问作者Eugenio.Gastelum96

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 13:50:09