pandas使用iterrows遍历时score列始终为0的解决方法
问题根因
pandas的iterrows()遍历返回的row是单行数据的临时副本,不是原DataFrame的绑定视图,所有对row的赋值修改只会作用在临时副本上,不会同步写回原表。你调试时看到row["score"] += localscore结果正确,是因为观察的是临时副本的值,循环结束后副本被回收,原表score列始终是初始值0。
另外你在循环里对joined_countries_without_duplicates做的去重操作也只改了副本,原表存储的还是带重复值的列表。
修复方案
- 最小改动修复:保留原有循环逻辑,循环内不对
row做赋值,计算完成后通过my_df.at[index, 列名]按索引定位原表位置,将结果直接写入原DataFrame。 - 推荐实现:弃用
iterrows()逐行循环,用pandas原生的向量化接口处理,无副本赋值问题,运行效率远高于逐行循环。
最小改动版代码
import pandas as pd my_df = pd.DataFrame({'countries': ["UK,DE", "DE", "DE"], "other_countries": ["DE", "PL", "PL"]}) scores = { "UK": 10.0, "DE": 20.0, "PL": 30.0 } my_df["joined_countries_without_duplicates"] = my_df["countries"] + "," + my_df["other_countries"] my_df["joined_countries_without_duplicates"] = my_df["joined_countries_without_duplicates"].str.split(",") my_df["score"] = 0 for index, row in my_df.iterrows(): unique_countries = list(set(row["joined_countries_without_duplicates"])) # 去重结果写回原表 my_df.at[index, "joined_countries_without_duplicates"] = unique_countries # 计算总分 localscore = sum(scores[country] for country in unique_countries) # 分数写回原表 my_df.at[index, "score"] = localscore
向量化优化版代码
import pandas as pd my_df = pd.DataFrame({'countries': ["UK,DE", "DE", "DE"], "other_countries": ["DE", "PL", "PL"]}) scores = { "UK": 10.0, "DE": 20.0, "PL": 30.0 } # 拼接、拆分、去重链式处理 my_df["joined_countries_without_duplicates"] = ( my_df["countries"] .str.cat(my_df["other_countries"], sep=",") .str.split(",") .apply(lambda x: list(set(x))) ) # 聚合计算分数 my_df["score"] = my_df["joined_countries_without_duplicates"].apply( lambda country_list: sum(scores[c] for c in country_list) )
两段代码运行后结果一致,三行的score值分别为30.0、50.0、50.0,符合预期。
内容的提问来源于stack exchange,提问作者funkurlif3
相关产品推荐
相关产品推荐

