基于Pandas GroupBy按条件为DataFrame父ID分配最终代码
问题背景与需求
原始DataFrame结构如下:
child_id parent_id code 111 null SS2 222 111 SS1 333 222 ZZZ 444 222 ZZZ 555 888 TTT 666 777 AAA 777 222 SS1 888 222 SS1 999 111 SS2
需生成新DataFrame,包含parent_id、code、final_code三个字段,规则为:
当某parent_id的所有子ID中,code与该父ID自身code相同的数量占比≥50%时,final_code赋值为父ID的code;否则赋值为NULL。
示例结果:
parent_id code final_code 222 SS1 SS1 111 SS2 SS2 888 SS1 NULL 777 SS1 NULL
判断逻辑说明:
- parent_id=222:4个子ID中2个code匹配父code(占比50%),赋值SS1;
- parent_id=111:2个子ID中1个匹配(占比50%),赋值SS2;
- parent_id=888:1个子ID不匹配,赋值NULL;
- parent_id=777:1个子ID不匹配,赋值NULL。
补充说明:DataFrame中每个child_id对应唯一code,多数child_id存在父ID(来自child_id列),parent_id列表示子ID间的关联关系。需用df.groupby('parent_id')实现,以下是具体实现技巧。
实现技巧与代码
步骤1:构建父ID的code映射表
首先提取每个child_id对应的code,用字典存储这一对应关系(因为parent_id本质是另一个child_id):
import pandas as pd # 构造原始数据 data = { 'child_id': [111, 222, 333, 444, 555, 666, 777, 888, 999], 'parent_id': [None, 111, 222, 222, 888, 777, 222, 222, 111], 'code': ['SS2', 'SS1', 'ZZZ', 'ZZZ', 'TTT', 'AAA', 'SS1', 'SS1', 'SS2'] } df = pd.DataFrame(data) # 生成parent_id到code的映射字典 parent_code_map = df.set_index('child_id')['code'].to_dict()
步骤2:给子项添加父code字段
过滤掉无父ID的根节点,给剩余子项添加对应父ID的code字段:
# 仅保留有父ID的子项数据 child_df = df[df['parent_id'].notna()].copy() # 映射父ID对应的code child_df['parent_code'] = child_df['parent_id'].map(parent_code_map)
步骤3:分组计算匹配占比
按parent_id分组,统计每组的子项总数、code匹配数量,进而计算匹配占比:
# 分组聚合统计 grouped = child_df.groupby('parent_id').agg( total_count=('child_id', 'count'), match_count=('code', lambda x: sum(x == child_df.loc[x.index, 'parent_code'])) ).reset_index() # 计算匹配占比 grouped['match_ratio'] = grouped['match_count'] / grouped['total_count']
步骤4:生成final_code并整理结果
关联父ID的code,根据占比条件赋值final_code,最后整理成目标格式:
# 添加父ID自身的code列 grouped['code'] = grouped['parent_id'].map(parent_code_map) # 按规则生成final_code grouped['final_code'] = grouped.apply( lambda row: row['code'] if row['match_ratio'] >= 0.5 else None, axis=1 ) # 筛选目标列并调整顺序(与示例结果对齐) result_df = grouped[['parent_id', 'code', 'final_code']].sort_values('parent_id', ascending=False).reset_index(drop=True)
执行后result_df即为符合要求的结果。
关键技巧说明
- 用字典映射快速获取父ID的code,避免重复查询提升效率;
- 分组聚合时结合索引匹配,确保准确计算每组的code匹配数量;
- 用
apply函数实现条件赋值,逻辑清晰易维护。
内容的提问来源于stack exchange,提问作者Nadiia
相关产品推荐
相关产品推荐

