如何用Pandas实现基于公共列的SQL式DataFrame关联更新?
Pandas实现基于匹配键的列更新(模拟SQL UPDATE SET WHERE)
我懂你这种想在Pandas里复刻SQL UPDATE逻辑的困惑!之前我也试过各种merge/join踩坑,其实有几个简洁的方法能搞定,完全不用循环,咱们一步步来:
首先先把你的测试数据用代码还原出来,方便测试:
import pandas as pd # 创建示例df1 df1 = pd.DataFrame({ 'key_col': [50, 49, 23], 'cola': ['foo', 'foo', 'bar'], 'colb': ['bar', 'bar', 'foo'], 'colc': ['foo', 'bla', 'bla'] }) # 创建示例df2 df2 = pd.DataFrame({ 'key_col': [23, 50], 'colz': ['something', 'something else'] })
方法一:字典映射法(最简洁直观)
核心思路是把df2转换成{key_col: colz}的字典映射,然后用map匹配赋值,最后用fillna保留未匹配行的原值:
# 将df2转换为key_col到colz的字典 key_col_to_colz = df2.set_index('key_col')['colz'].to_dict() # 更新colc:匹配到的用字典值,未匹配的保留原colc内容 df1['colc'] = df1['key_col'].map(key_col_to_colz).fillna(df1['colc'])
运行后得到的df1就是你想要的结果:
key_col cola colb colc 0 50 foo bar something else 1 49 foo bar bla 2 23 bar foo something
方法二:左连接+合并更新法
如果需要同时更新多列,这种方法更灵活。先通过左连接把df2的列合并过来,再用combine_first保留原值:
# 左连接df1和df2,只引入df2的colz列 merged_df = df1.merge(df2, on='key_col', how='left') # 用colz的值覆盖colc,未匹配的行保留原colc内容 merged_df['colc'] = merged_df['colz'].combine_first(merged_df['colc']) # 移除临时的colz列,得到最终df1 df1 = merged_df.drop('colz', axis=1)
方法三:loc精准定位赋值法
直接定位到df1中key_col存在于df2的行,精准赋值,不影响其他行:
# 先创建key到colz的映射 colz_map = df2.set_index('key_col')['colz'] # 定位匹配行,直接更新colc df1.loc[df1['key_col'].isin(df2['key_col']), 'colc'] = df1['key_col'].map(colz_map)
小提示:为什么之前merge/join会失败?
很多人直接merge后直接赋值df1['colc'] = merged['colz'],这样会把未匹配行的colc改成NaN,忘记用fillna或者combine_first保留原值,这是最容易踩的坑!
内容的提问来源于stack exchange,提问作者RookieCookie
相关产品推荐
相关产品推荐

