基于灵活条件合并两个Pandas DataFrame的优化实现问询
嘿,针对你这个用df2条件填充df1factor字段的需求,我有两个简洁且易维护的方案,完全避开布尔掩码嵌套和复杂if列表,一起来看看:
方案1:映射字典 + apply
这个方案把df2的规则转换成结构化的字典映射,逻辑清晰,后续改规则只需要调整字典或df2即可,不用动核心逻辑。
首先假设你的df2结构大概是这样(带通配符*的规则表):
| counterparty | term | factor |
|---|---|---|
| bank | * | 1 |
| client | 1Y | 0.5 |
| client | 3Y | 0.7 |
我们先把df2转成嵌套映射字典,用__default__标记通配符对应的默认规则:
# 将df2转换为嵌套映射字典,处理通配符* factor_map = {} for _, row in df2.iterrows(): cp = row["counterparty"] term = row["term"] factor_val = row["factor"] if cp not in factor_map: factor_map[cp] = {} if term == "*": # 用特殊键存储通配符对应的默认值 factor_map[cp]["__default__"] = factor_val else: factor_map[cp][term] = factor_val # 定义匹配函数,按规则返回factor值 def match_factor(row): # 获取当前对手方的规则映射 cp_rules = factor_map.get(row["counterparty"], {}) # 优先匹配具体期限,没有则用默认规则 return cp_rules.get(row["term"], cp_rules.get("__default__")) # 填充df1的factor字段 df1["factor"] = df1.apply(match_factor, axis=1)
方案2:Pandas原生合并 + fillna
如果你的数据量较大,这个方案更高效——完全用Pandas的原生操作,不用循环和apply:
# 拆分df2的规则:通配符默认规则 和 具体期限规则 default_rules = df2[df2["term"] == "*"].drop("term", axis=1) specific_rules = df2[df2["term"] != "*"] # 第一步:合并具体期限规则,匹配到对应的值 df1 = df1.merge( specific_rules, on=["counterparty", "term"], how="left", suffixes=("", "_tmp") ) # 第二步:合并默认规则,填充未匹配到的空值 df1 = df1.merge( default_rules, on="counterparty", how="left", suffixes=("", "_default") ) # 优先用具体规则的值,无匹配则用默认规则 df1["factor"] = df1["factor_tmp"].fillna(df1["factor_default"]) # 清理临时列 df1 = df1.drop(["factor_tmp", "factor_default"], axis=1)
方案优势
这两个方案都有很好的扩展性:以后要新增对手方或期限规则,只需要在df2里新增一行即可,不用修改核心代码逻辑;同时完全避开了复杂的布尔掩码(比如(df1['counterparty'] == 'bank') & (df1['term'] == ...))和多层嵌套的if语句,代码可读性拉满。
内容的提问来源于stack exchange,提问作者Number Logic
相关产品推荐
相关产品推荐

