基于provider_name匹配两个pandas DataFrame新增指定列
解决方案
你这个场景是典型的「小维度表给大事实表做属性匹配」,最简洁高效的写法是用pandas的映射匹配,不需要写循环,2万多行数据毫秒级就能跑完,还不会打乱原表顺序。
- 第一步:从第二个信息表提取匹配用的映射关系,样例里第二个表共345行,每个
provider_name只对应唯一一条机构记录,直接把机构名设为索引,取需要的两列即可:
attr_map = df2.set_index('provider_name')[['ownership_type', 'total_number_of_beds']]
如果后续第二个表可能出现同一个机构多条重复记录的情况,加个去重逻辑更稳妥:
attr_map = df2.drop_duplicates('provider_name').set_index('provider_name')[['ownership_type', 'total_number_of_beds']]
- 第二步:直接按
provider_name做映射赋值到第一个表即可,同一个机构名对应的所有行都会自动填充上匹配到的属性值:
df1[['ownership_type', 'total_number_of_beds']] = df1['provider_name'].map(attr_map)
如果有部分机构名在第二个表里找不到对应信息,匹配结果会是空值,你可以根据业务需要填充默认值,比如:
df1[['ownership_type', 'total_number_of_beds']] = ( df1['provider_name'] .map(attr_map) .fillna({'ownership_type': '未知', 'total_number_of_beds': 0}) )
如果你更习惯用表连接的写法,用左连接也能实现同样效果,注意要指定how='left'保留第一个表的所有行:
df1 = df1.merge( df2[['provider_name', 'ownership_type', 'total_number_of_beds']].drop_duplicates('provider_name'), on='provider_name', how='left' )
对比下来map的写法性能更好,不会出现merge可能带来的行顺序偏移、同名列自动加后缀的问题,更适合单键匹配补列的场景。
内容的提问来源于stack exchange,提问作者Frederick Almond
相关产品推荐
相关产品推荐

