itertuples循环中使用.at无法实时更新row值的技术问询
问题根源
itertuples()返回的是不可变命名元组,一旦生成,里面的字段值就固定为生成时的快照,后续修改df_group不会同步更新已生成的row对象。- 你操作的
df_group是原DataFrame的分组副本,修改它不会影响原df,你看到的Age更新只是副本里的变化,原df其实并未被修改。
解决方案
方案1:用矢量化操作替代循环(推荐,符合Pandas最佳实践)
Pandas的核心优势是矢量化运算,比循环高效得多,直接批量完成修改:
import pandas as pd data = {'Name': ['A', 'B', 'C', 'D', 'A', 'B', 'D'], 'Age': [20, 21, 19, 18, 21, 19, 18], 'Size': [7, 7, 9, 8, 7, 9, 8]} df = pd.DataFrame(data).sort_values(by='Name').reset_index(drop=True) # 批量将Age=20的改为25 df.loc[df['Age'] == 20, 'Age'] = 25 # 直接同步New_age为最新的Age值 df['New_age'] = df['Age'] print(df)
方案2:必须分组处理时用apply
如果有其他分组专属逻辑,用groupby.apply实现更简洁:
import pandas as pd data = {'Name': ['A', 'B', 'C', 'D', 'A', 'B', 'D'], 'Age': [20, 21, 19, 18, 21, 19, 18], 'Size': [7, 7, 9, 8, 7, 9, 8]} df = pd.DataFrame(data).sort_values(by='Name').reset_index(drop=True) df['New_age'] = 0 def process_group(group): # 修改分组内符合条件的Age group.loc[group['Age'] == 20, 'Age'] = 25 # 赋值最新的Age给New_age group['New_age'] = group['Age'] return group df = df.groupby('Name', group_keys=False).apply(process_group) print(df)
方案3:保留循环但修正逻辑
如果一定要用循环遍历,需注意两点:
- 直接操作原DataFrame(而非分组副本),确保修改生效
- 避免依赖已生成的row快照,直接从DataFrame取最新值
import pandas as pd data = {'Name': ['A', 'B', 'C', 'D', 'A', 'B', 'D'], 'Age': [20, 21, 19, 18, 21, 19, 18], 'Size': [7, 7, 9, 8, 7, 9, 8]} df = pd.DataFrame(data).sort_values(by='Name').reset_index(drop=True) df['New_age'] = 0 df_grouped = df.groupby(['Name']) for group_name, df_group in df_grouped: # 用iterrows遍历,获取每行索引和数据 for idx, row in df_group.iterrows(): if row['Age'] == 20: # 直接修改原df的Age df.at[idx, 'Age'] = 25 # 从原df取最新的Age值赋值给New_age df.at[idx, 'New_age'] = df.at[idx, 'Age'] print(df)
内容的提问来源于stack exchange,提问作者JDK
相关产品推荐
相关产品推荐

