如何在Pandas中匹配并替换不同数据集的指定列值?
Pandas 数据集匹配更新解决方案
现有数据集
df1(更新后的数据)
area date aa bb cc japan 10/1/2027 1 0 0 us 1/1/2022 5 5 5 fiji 11/2/2026 1 1 1
df2(旧数据)
area date aa bb cc stat japan 10/1/2027 0 5 5 yes fiji 11/2/2026 0 0 10 no
需求
当area和date值完全匹配时,将df2中的aa、bb、cc列值替换为df1中的对应更新值,最终期望输出:
area date aa bb cc stat japan 10/1/2027 1 0 0 yes fiji 11/2/2026 1 1 1 no
完整实现方案
以下提供两种高效的实现方式,可根据实际场景选择:
方法一:利用set_index + update(直接覆盖匹配行)
这种方法效率较高,适合仅需要覆盖匹配行的场景:
import pandas as pd import numpy as np # 构建示例数据(实际使用时替换为你的数据集) df1 = pd.DataFrame({ 'area': ['japan', 'us', 'fiji'], 'date': ['10/1/2027', '1/1/2022', '11/2/2026'], 'aa': [1,5,1], 'bb': [0,5,1], 'cc': [0,5,1] }) df2 = pd.DataFrame({ 'area': ['japan', 'fiji'], 'date': ['10/1/2027', '11/2/2026'], 'aa': [0,0], 'bb': [5,0], 'cc': [5,10], 'stat': ['yes', 'no'] }) # 处理日期空值(适配你的现有代码,确保空日期不会干扰匹配) df2['date'] = df2['date'].apply(lambda x: np.nan if x == ' ' else x) df1['date'] = df1['date'].apply(lambda x: np.nan if x == ' ' else x) # 设置匹配索引:以area和date作为唯一标识键 df1_indexed = df1.set_index(['area', 'date']) df2_indexed = df2.set_index(['area', 'date']) # 仅更新指定的aa、bb、cc列 df2_indexed[['aa', 'bb', 'cc']].update(df1_indexed[['aa', 'bb', 'cc']]) # 重置索引恢复原数据结构 result = df2_indexed.reset_index() print(result)
方法二:利用merge合并后填充(灵活处理部分匹配)
如果需要保留未匹配行的旧值,或需要更灵活的逻辑,可使用merge方法:
import pandas as pd import numpy as np # 构建示例数据 df1 = pd.DataFrame({ 'area': ['japan', 'us', 'fiji'], 'date': ['10/1/2027', '1/1/2022', '11/2/2026'], 'aa': [1,5,1], 'bb': [0,5,1], 'cc': [0,5,1] }) df2 = pd.DataFrame({ 'area': ['japan', 'fiji'], 'date': ['10/1/2027', '11/2/2026'], 'aa': [0,0], 'bb': [5,0], 'cc': [5,10], 'stat': ['yes', 'no'] }) # 处理日期空值 df2['date'] = df2['date'].apply(lambda x: np.nan if x == ' ' else x) df1['date'] = df1['date'].apply(lambda x: np.nan if x == ' ' else x) # 重命名df1的列,避免合并后列名冲突 df1_renamed = df1.rename(columns={'aa': 'aa_new', 'bb': 'bb_new', 'cc': 'cc_new'}) # 以area和date为键合并两个数据集,保留df2的所有行 merged = df2.merge(df1_renamed, on=['area', 'date'], how='left') # 替换逻辑:有更新值则用新值,无则保留旧值 merged['aa'] = merged['aa_new'].fillna(merged['aa']) merged['bb'] = merged['bb_new'].fillna(merged['bb']) merged['cc'] = merged['cc_new'].fillna(merged['cc']) # 删除临时新增的列 result = merged.drop(['aa_new', 'bb_new', 'cc_new'], axis=1) print(result)
内容的提问来源于stack exchange,提问作者Lynn
相关产品推荐
相关产品推荐

