基于日期与名称匹配将DataFrame数据合并到时间序列DataFrame
问题描述
我有两个Pandas DataFrame:
- df1是时间序列DataFrame,索引为Date,包含6列数据,其中一列是'name'列,'pick'列初始全为NaN
- df2所有行的Date值相同,每行的'name'是唯一字符串,包含'pick'列
df1结构
| Date | name | score | stat1 | stat2 | pick |
|---|---|---|---|---|---|
| 2022-1-1 | ABC | 23.3 | 0.234 | 34 | NaN |
| 2022-1-2 | ABC | 21.1 | 0.431 | 14 | NaN |
| 2022-1-3 | ABC | 29.9 | 1.310 | 4 | NaN |
| 2022-1-4 | ABC | 11.3 | 9.310 | 3 | NaN |
df2结构
| index | Date | name | pick |
|---|---|---|---|
| 0 | 2022-1-3 | QRS | 23.3 |
| 1 | 2022-1-3 | ABC | 21.1 |
| 2 | 2022-1-3 | DBA | 29.9 |
| 3 | 2022-1-3 | KLL | 11.3 |
我想基于name和Date双条件,把df2中的对应pick值合并到df1中,尝试了以下代码但不符合预期:
df3['pick'] = pd.merge(df1, df2, how='outer', on=['name'])
期望结果:生成新的df3(或更新df1),仅将df1中Date=2022-1-3且name=ABC的行的pick列设为21.1,其余行保持NaN,结构如下:
| Date | name | score | stat1 | stat2 | pick |
|---|---|---|---|---|---|
| 2022-1-1 | ABC | 23.3 | 0.234 | 34 | NaN |
| 2022-1-2 | ABC | 21.1 | 0.431 | 14 | NaN |
| 2022-1-3 | ABC | 29.9 | 1.310 | 4 | 21.1 |
| 2022-1-4 | ABC | 11.3 | 9.310 | 3 | NaN |
解决方案
你之前的代码问题在于只按name合并,未加入Date作为匹配条件,且直接赋值给df3['pick']会因merge返回完整DataFrame导致错误。以下是两种可行实现方式:
方法1:使用merge精准匹配后更新列
# 将df1的Date索引转为列,方便和df2的Date列匹配 df1_reset = df1.reset_index() # 基于Date和name做左连接,仅保留df2中需要的列 merged = pd.merge(df1_reset, df2[['Date', 'name', 'pick']], on=['Date', 'name'], how='left') # 用df2的pick值覆盖原pick列,无匹配项保留原NaN merged['pick'] = merged['pick_y'].combine_first(merged['pick_x']) # 恢复Date为索引,整理成目标结构 df3 = merged.set_index('Date')[['name', 'score', 'stat1', 'stat2', 'pick']]
方法2:构建匹配字典实现快速映射
# 构建以(Date, name)为键、pick为值的字典 pick_dict = df2.set_index(['Date', 'name'])['pick'].to_dict() # 复制df1避免修改原数据,逐行匹配双条件赋值 df3 = df1.copy() df3['pick'] = df3.apply(lambda row: pick_dict.get((row.name, row['name']), pd.NA), axis=1)
内容的提问来源于stack exchange,提问作者chorink65
相关产品推荐
相关产品推荐

