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

对pandas groupby对象重复执行agg修改原始dataframe的问题求解

问题原因
  1. 核心问题出自可变对象的引用传递:你存储在DataFrame中的字典、列表都属于Python可变对象,聚合函数里out[k] = v的写法是直接把原列表的引用赋值给out字典的键,后续执行out[k].extend(v)操作时,会直接修改原DataFrame中存储的列表本身,而非操作独立副本。
  2. 你对深拷贝的使用方式存在错误:cp.deepcopy(grouped['probe_dict'])没有实际作用,groupby对象仅持有底层数据的引用,拷贝它不会复制实际数据;即便你对DataFrame做了深拷贝,只要聚合函数里直接操作原列表引用,还是会修改你传入的df数据(传入副本则改副本,传入原df则改原df)。
解决方法

最优方案:修改聚合函数,从根源避免修改原对象

赋值时直接拷贝列表,不再引用原DataFrame中的列表对象,修改后的函数如下:

def merge_probe_trial_dicts(x, only_last=None):
    """ 
    传入pandas groupby聚合的函数,用于按被试和任务合并字典
    
    参数:
    =========================
    x: agg方法传入的分组数据
    only_last (int): 每个转换仅保留最后n个探针试次
    """
    out = {}
    for d in x.dropna():
        for k, v in d.items():
            if k not in out:
                # 新增列表拷贝操作,不直接引用原列表
                out[k] = v.copy()
            else:
                out[k].extend(v)
                
    if only_last:
        for k, v in out.items():
            out[k] = v[-only_last:]
    return out

辅助优化:调整深拷贝的使用逻辑

不需要拷贝groupby对象,如果需要完全隔离原DataFrame,可以提前单独拷贝DataFrame再做分组,示例代码如下:

import copy as cp
from functools import partial

# 单独拷贝DataFrame,避免后续操作影响原数据
df_copy = cp.deepcopy(df4)
grouped = df_copy.groupby(['subject','task_nr'])
mptd_only30 = partial(merge_probe_trial_dicts, only_last=30)
# 直接对分组后的列执行聚合即可,不需要拷贝groupby对象
mergag = grouped['probe_dict'].agg(mptd_only30)

内容的提问来源于stack exchange,提问作者user3235916

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.17 03:06:10