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

为何函数会原地修改pd.DataFrame?且仅修改至首个.drop前?

Pandas原地修改问题解析

为什么函数内变量赋值会改到原DataFrame?

Pandas的DataFrame是引用类型,当你在函数里写df = input_df时,只是让df这个变量指向了和原输入完全相同的内存对象。这时候如果对df做原地修改操作(比如直接修改列值df['col'] = ...、df.fillna(inplace=True)这类带inplace=True的方法),本质就是在修改原对象的内存数据,自然会影响到函数外的原DataFrame。

为什么修改仅停留在首个.drop操作前?

如果你的.drop是用df = df.drop(...)(不带inplace=True)的形式,那问题就出在这:.drop会返回一个全新的DataFrame对象,执行这行代码后,df变量会重新指向这个新对象,和原输入的内存地址彻底断开了。所以在这之后对df的所有操作,都只会作用在新对象上,不会影响原输入。而在这之前的操作,都是在原对象上做的原地修改,所以能被外部看到。

举个直观的例子:

def process_df(input_df):
    df = input_df
    # 这一步是原地修改原对象,外部能看到变化
    df['new_col'] = 1
    # 这一步返回新对象,df指向新内存,和原输入彻底无关
    df = df.drop('old_col', axis=1)
    # 后续操作只改新对象,原输入不受影响
    df['another_col'] = 2
    return df

这时候原输入的DataFrame会新增new_col,但不会丢失old_col,也不会有another_col——因为drop之后df已经不是原来的那个对象了。

为什么Polars没有这个问题?

Polars的核心设计就是默认不可变,几乎所有操作都会返回一个新的DataFrame对象,不会修改原数据本身。哪怕你在函数里写pl_df = input_pl_df,后续对pl_df做的任何操作(比如.drop)都会生成新对象,原输入的Polars DataFrame始终保持初始状态。只有极少数低层级场景才会涉及原地操作,日常使用根本碰不到,所以不会出现Pandas这种意外修改原数据的情况。

怎么解决Pandas的这个问题?

最简单的办法就是在函数开头先复制原DataFrame,彻底断开引用关系:

def process_df(input_df):
    # 深拷贝,完全独立于原对象
    df = input_df.copy(deep=True)
    # 后续所有操作都在副本上,不会影响原数据
    df['new_col'] = 1
    df = df.drop('old_col', axis=1)
    df['another_col'] = 2
    return df

如果你的DataFrame没有嵌套结构(比如没有包含列表、字典的列),用copy(deep=False)(浅拷贝)也能满足需求,速度会更快。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 11:25:57