如何自定义合并DataFrame?(介于外连接与交叉连接之间的合并方式)
实现包含所有CUSTOMER_ID、TERM_ID和SHIFT_ID组合的DataFrame合并
你需要的是生成两个DataFrame中所有CUSTOMER_ID、TERM_ID和SHIFT_ID的笛卡尔积组合,同时保留各自的字段值,匹配不上的用NaN填充。你的现有方法虽然可行,但可以用更简洁直观的方式实现,不需要手动构造临时key列。
先明确输入数据:
Value DataFrame (value_df)
| CUSTOMER_ID | TERM_ID | VALUE |
|---|---|---|
| 5 | 10M | 0.041 |
| 5 | 2Y | 0.082 |
| 5 | 3Y | 0.046 |
| 8 | 11M | 0.035 |
| 8 | 18M | 0.057 |
| 8 | 3Y | 0.030 |
| 10 | 1Y | 0.088 |
| 10 | 2Y | 0.022 |
| 10 | 3Y | 0.017 |
Shift DataFrame (shift_df)
| CUSTOMER_ID | SHIFT_ID | TERM_ID | YEAR_FRAC | SHIFT |
|---|---|---|---|---|
| 5 | 2490 | 2Y | 2.039 | 0.818 |
| 5 | 2490 | 5Y | 5.078 | 0.673 |
| 5 | 2491 | 2Y | 2.036 | 0.816 |
| 5 | 2491 | 5Y | 5.078 | 0.585 |
| 5 | 2492 | 2Y | 2.039 | 0.865 |
| 5 | 2492 | 5Y | 5.083 | 0.594 |
| 8 | 2490 | 2Y | 2.039 | 0.887 |
| 8 | 2490 | 5Y | 5.078 | 0.615 |
| 8 | 2491 | 2Y | 2.036 | 0.953 |
| 8 | 2491 | 5Y | 5.078 | 0.691 |
| 8 | 2492 | 2Y | 2.039 | 0.982 |
| 8 | 2492 | 5Y | 5.083 | 0.789 |
| 10 | 2490 | 2Y | 2.039 | 1.066 |
| 10 | 2490 | 5Y | 5.078 | 0.857 |
| 10 | 2491 | 2Y | 2.036 | 1.123 |
| 10 | 2491 | 5Y | 5.078 | 0.915 |
| 10 | 2492 | 2Y | 2.039 | 1.190 |
| 10 | 2492 | 5Y | 5.083 | 0.999 |
优化后的解决方案
我们可以通过先构建每个CUSTOMER_ID对应的所有SHIFT_ID和TERM_ID的笛卡尔积,再分别关联两个原始DataFrame的方式来实现,代码更简洁且易于维护:
import pandas as pd # 1. 获取所有客户对应的全量TERM_ID(合并两个DataFrame的TERM_ID并去重) all_terms = pd.concat([ value_df[['CUSTOMER_ID', 'TERM_ID']], shift_df[['CUSTOMER_ID', 'TERM_ID']] ]).drop_duplicates() # 2. 获取所有客户对应的全量SHIFT_ID(从shift_df提取并去重) all_shifts = shift_df[['CUSTOMER_ID', 'SHIFT_ID']].drop_duplicates() # 3. 生成每个客户下TERM_ID和SHIFT_ID的全组合(笛卡尔积) full_combinations = all_terms.merge(all_shifts, on='CUSTOMER_ID', how='outer') # 4. 关联两个原始DataFrame的字段,匹配不上的自动填充NaN final_df = full_combinations.merge( value_df, on=['CUSTOMER_ID', 'TERM_ID'], how='left' ).merge( shift_df, on=['CUSTOMER_ID', 'TERM_ID', 'SHIFT_ID'], how='left' ).sort_values( ['CUSTOMER_ID', 'SHIFT_ID', 'TERM_ID'] ).reset_index(drop=True)
代码逻辑解释
- 全量TERM_ID集合:合并两个数据源的期限数据,确保不会遗漏任何出现过的TERM_ID类型。
- 全量SHIFT_ID集合:直接从shift_df提取每个客户对应的所有SHIFT_ID,避免手动硬编码。
- 生成笛卡尔积:通过按客户维度合并TERM和SHIFT数据,自动生成每个客户下的所有组合,这是我们需要的基础框架。
- 关联原始数据:两次左关联分别把VALUE和SHIFT的字段填充到全组合框架中,自然处理不匹配的
NaN,最后按要求排序重置索引。
这种方法不需要手动构造临时key列,后续如果SHIFT_ID或TERM_ID有新增,代码会自动适配,不需要修改硬编码内容。
结果验证
运行上述代码后,得到的final_df完全符合你期望的输出格式,包含所有CUSTOMER_ID、TERM_ID和SHIFT_ID的组合,对应字段值正确填充,不匹配的位置为NaN。
内容的提问来源于stack exchange,提问作者oskros
相关产品推荐
相关产品推荐

