遍历两个pandas DataFrame匹配赋值时触发KeyError报错求解
报错根因
- 循环索引逻辑完全错误:
for i in df_1['location_name']遍历得到的i是列里的具体值(比如触发报错的Afghanistan就是第一个国家名),不是DataFrame的行位置/行标签。后续写df_1['location_name'][i]时,pandas会把这个字符串当成行索引键查找,而你的行索引默认是从0开始的整数,自然找不到对应键抛出KeyError。 - 手写三层嵌套循环效率极低,数据量稍大就会卡顿,pandas原生提供表关联接口,不需要手写循环做字段匹配。
- 取值逻辑错误:代码里
df_2.iloc[len(k),4 + len(k)]用字符串长度len(k)当行号、列偏移量,完全不可能定位到正确的GDP单元格。
正确实现方案
你的需求本质是两个表按「国家名+年份」做关联匹配,直接用pandas内置的表关联方法即可,不需要写循环:
import pandas as pd # 1. 先把df_2从宽表转为长表:原本每一列对应一个年份的GDP,转完后每一行对应「国家+年份+GDP值」 df_2_long = df_2.melt( id_vars=["Country Name"], value_vars=df_2.columns[4:], # df_2前4列是国家属性,从第5列开始是各年份GDP var_name="year", value_name="GDP" ) # 统一年份列类型,和df_1的年份字段类型保持一致,避免类型不匹配导致关联失败 df_2_long["year"] = df_2_long["year"].astype(int) # 按你df_1的年份实际类型调整,比如字符串就改str # 2. 关联两个表,把GDP匹配到df_1 # 注意:如果你的df_1里年份列名不是year,把下面left_on里的'year'改成你实际的列名 df_1 = df_1.merge( df_2_long[["Country Name", "year", "GDP"]], left_on=["location_name", "year"], right_on=["Country Name", "year"], how="left" # 左连接保留df_1所有行,匹配不到GDP的行自动填充NaN ) # 删掉关联产生的冗余列 df_1.drop(columns=["Country Name"], inplace=True)
如果你只需要匹配某一个固定年份的GDP,不需要转长表,直接做映射即可,比如匹配2020年GDP:
# 构建国家到对应年份GDP的映射字典 gdp_2020_map = df_2.set_index("Country Name")["2020"].to_dict() # 直接批量赋值,效率远高于循环 df_1["GDP"] = df_1["location_name"].map(gdp_2020_map)
内容的提问来源于stack exchange,提问作者RafiP
相关产品推荐
相关产品推荐

