Python DataFrame两种赋值方式差异及strip失效问题咨询
两种DataFrame赋值写法的差异解析
咱们先直击核心:你碰到的问题本质是Python变量引用规则和Pandas DataFrame的赋值逻辑共同导致的,下面把两种写法的区别拆解开说清楚:
1. 第一种写法:dataFrame[:] = dataFrame.apply(...)
这种写法是原地修改传入的原DataFrame对象:
dataFrame[:]是对整个DataFrame的切片赋值,它的作用是直接修改原对象内部的所有数据,而不是创建一个新的DataFrame。- 所以函数内部的
dataFrame变量始终指向你传入的test_df,这也是为什么你看到两者的id完全一致(都是4647827832)。 apply处理后的结果直接覆盖原对象的内容,因此外部的test_df也会同步看到修改后的结果(比如dm列的制表符被strip掉,剩下的' yes'是原数据自带的空格)。
2. 第二种写法:dataFrame = dataFrame.apply(...)
这种写法只是重新绑定函数内的局部变量,完全没碰原对象:
dataFrame.apply(...)会生成一个全新的DataFrame对象,当你执行dataFrame = ...时,只是把函数内部的局部变量dataFrame指向了这个新对象,但外部的test_df仍然指向最初传入的那个旧对象。- 你看到的
id(test_df)和函数内的id(dataFrame)不一样,就是因为函数内的变量已经换了指向的对象,而外部的test_df还是原来的那个。至于输出里的nan,是因为你先执行了replace("\\?", np.nan, inplace=True),这个操作已经原地修改了原test_df把?换成了nan,但后面的apply处理的是新对象,外部的test_df没拿到这个处理后的结果,所以保留了replace后的nan。
为什么函数外直接执行strip正常?
当你在函数外写test_df = test_df.apply(...)时,是直接把全局变量test_df指向了apply生成的新对象,自然能看到修改后的结果。但在函数内只做局部变量赋值的话,外部变量不会受到任何影响。
推荐的正确做法
如果想在函数内处理DataFrame,更清晰的方式有两种:
- 继续用原地修改的方式:保持
dataFrame[:] = ...的写法,确保原对象被修改; - 采用返回新对象的方式(更推荐,避免原地修改的副作用):
def FillMissing(dataFrame): # 先复制原数据,避免修改原对象 df_processed = dataFrame.replace("\\?", np.nan, regex=True) df_processed = df_processed.apply(lambda x: x.str.strip("\t") if x.dtype == "object" else x) print(id(df_processed)) return df_processed # 外部调用时接收返回的新对象 test_df = FillMissing(test_df)
内容的提问来源于stack exchange,提问作者Vaebhav
相关产品推荐
相关产品推荐

