You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何参照df1层级规则修正df2分类字段并简化Pandas合并代码

问题需求

df1为标准层级映射表,存储了small_class→big_class→category的正确对应关系,示例数据如下:

category  category_id big_class  big_class_id small_class  small_class_id
0        A            1        a1            11         aa1             111
1        A            1        a2            12         aa2             112
2        B            2        b1            21         bb1             221
3        B            2        b2            22         bb2             222
4        B            2        b3            23         bb3             223

df2为待修正的业务数据表,其中层级字段存在错误,需要以df1的映射关系为标准,按照细粒度优先的规则修正所有层级字段,匹配优先级:small_class > big_class > category。df2示例数据如下:

item small_class  small_class_id  ... big_class_id  category category_id
0  aaa1         aa1           111.0  ...         12.0         B         2.0
1  aaa2         aa2           112.0  ...         11.0       NaN         NaN
2  bbb3         NaN             NaN  ...          NaN         B         2.0
3  bbb4         bb3           223.0  ...          NaN         A         1.0
4  bbb1         NaN             NaN  ...         23.0         A         1.0

最终预期输出:

item small_class  small_class_id  ... big_class_id     category category_id
0  aaa1         aa1           111.0  ...         11.0            A           1
1  aaa2         aa2           112.0  ...         12.0            A           1
2  bbb3         NaN             NaN  ...          NaN            B           2
3  bbb4         bb3           223.0  ...         23.0            B           2
4  bbb1         NaN             NaN  ...         22.0            B           2
简洁实现方案

下面两种方案都比原实现逻辑更清晰、代码更简洁:

方案1:左连+空值填充(性能更优,适合大数据量)

# 第一步:以small_class为键关联标准表,匹配到的字段直接覆盖原值
tmp = df2.merge(df1, on="small_class", how="left", suffixes=("_old", ""))

# 第二步:剩余未匹配到的行,以big_class为键关联标准表上层字段
bc_ref = df1.drop_duplicates("big_class")[["big_class", "big_class_id", "category", "category_id"]]
tmp = tmp.merge(bc_ref, on="big_class", how="left", suffixes=("", "_bc"))

# 第三步:按优先级填充空值,细粒度匹配结果>粗粒度匹配结果>原值
fix_cols = ["category", "category_id", "big_class_id", "small_class_id"]
for col in fix_cols:
    tmp[col] = tmp[col].fillna(tmp[f"{col}_bc"]).fillna(tmp[f"{col}_old"])

# 输出结果保留所需字段
res = tmp[["item", "small_class", "small_class_id", "big_class", "big_class_id", "category", "category_id"]]

方案2:行级自定义函数(逻辑更直观,适合小数据量、规则灵活调整场景)

import pandas as pd

# 提前构建不同粒度的映射字典
sc_map = df1.set_index("small_class").to_dict("index")
bc_map = df1.drop_duplicates("big_class").set_index("big_class")[["big_class_id", "category", "category_id"]].to_dict("index")

def fix_level(row):
    # 优先用small_class匹配全量层级
    if pd.notna(row["small_class"]) and row["small_class"] in sc_map:
        return pd.Series(sc_map[row["small_class"]])
    # 匹配失败再用big_class匹配上层层级
    if pd.notna(row["big_class"]) and row["big_class"] in bc_map:
        return pd.Series({**row.to_dict(), **bc_map[row["big_class"]]})
    # 都匹配失败保留原值
    return row

res = df2.apply(fix_level, axis=1)

内容的提问来源于stack exchange,提问作者ah bon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 14:42:01