为何遍历Pandas DataFrame修改不生效?与Python列表差异解析
为什么遍历修改Pandas DataFrame不生效,而列表可以?
先看两个对比示例:
示例1:列表修改生效
u=[68, 82, 75] v=[92, 54, 71, 56] for x in [u,v]: x[0]=100 print(u) # 输出 [100, 82, 75] print(v) # 输出 [100, 54, 71, 56]
这个例子里,u和v的第一个元素都被成功改成100,符合预期。
示例2:DataFrame修改不生效
import pandas as pd data_current = [['tom', 72], ['nick', 77], ['julie', 68]] data_desired = [['mary', 65], ['john', 73], ['Alex', 74]] # 创建DataFrame df_current = pd.DataFrame(data_current, columns=['Name', 'Height']) df_desired = pd.DataFrame(data_desired, columns=['Name', 'Height']) # 尝试过滤身高>70的行 for df in [df_current, df_desired]: df=df[df['Height']>70] print("Current Roster:") print(df_current) # 仍然保留所有行 print("Desired Roster:") print(df_desired) # 仍然保留所有行
这里循环里的过滤操作完全没生效,原DataFrame一点没变。
核心原因:变量引用的区别
Python里的变量本质是对象的引用,这两个例子的关键差异在于:
列表示例中,
x[0]=100是直接修改原对象:
循环里的x是原列表u/v的引用,修改x的元素时,是直接在u/v指向的那个列表对象上操作,所以外部的u/v能看到变化。DataFrame示例中,
df=df[df['Height']>70]是替换了引用的对象:df[df['Height']>70]会生成一个新的DataFrame对象(过滤后的结果),然后把循环变量df重新指向这个新对象。但原来的df_current/df_desired还是指向最初创建的那个旧DataFrame对象,完全没被改动,所以外部打印时还是原来的数据。
正确的修改方式
如果要在循环里修改原DataFrame,有两种常见做法:
方法1:用inplace操作(直接修改原对象)
for df in [df_current, df_desired]: # 直接在原对象上删除不符合条件的行 df.drop(df[df['Height'] <= 70].index, inplace=True)
方法2:遍历索引,重新赋值给原变量
dfs = [df_current, df_desired] for i in range(len(dfs)): dfs[i] = dfs[i][dfs[i]['Height'] > 70] # 把结果重新赋值给原变量 df_current, df_desired = dfs
方法3:生成新的DataFrame列表
如果不需要保留原对象,直接生成新列表即可:
filtered_dfs = [df[df['Height']>70] for df in [df_current, df_desired]] df_current, df_desired = filtered_dfs
内容的提问来源于stack exchange,提问作者Still learning
相关产品推荐
相关产品推荐

