如何在Pandas中按分组结合条件判断,依自定义层级优先级筛选唯一ID结果
Pandas 多优先级组内取最优记录实现方案
核心实现思路
完全不需要手动遍历分组、再逐组拼接结果。直接把两个维度的优先级规则转换为Pandas可识别的自定义排序权重,配合分组取首位记录的逻辑,就能直接匹配两步筛选的预期效果,相比循环遍历的写法代码更简洁、大数据量下效率高一个量级。
分步实操代码
1. 绑定自定义优先级权重
利用Pandas的有序分类(Categorical)类型,直接给两个Tier字段绑定你定义的优先级顺序,不需要手动做数值映射:
- Tier1 优先级:
RF > OK > LO,按优先级从高到低定义分类顺序即可 - Tier2 优先级:
B > E,同理定义分类顺序
import pandas as pd # 初始化给出的原始测试数据 df = pd.DataFrame({ 'ID': [1111, 1111, 2222, 2222, 3333, 3333], 'Tier1': ['RF', 'OK', 'RF', 'RF', 'OK', 'LO'], 'Tier2': ['B', 'B', 'B', 'E', 'B', 'B'] }) # 定义自定义优先级顺序,顺序越靠前优先级越高 tier1_priority = ['RF', 'OK', 'LO'] tier2_priority = ['B', 'E'] # 将字段转换为带有序优先级的分类类型 df['Tier1'] = pd.Categorical(df['Tier1'], categories=tier1_priority, ordered=True) df['Tier2'] = pd.Categorical(df['Tier2'], categories=tier2_priority, ordered=True)
2. 一步完成两步筛选逻辑
直接对全表按两个字段的优先级排序,之后按ID分组取每组的第一条记录,这个过程完全复现你描述的两步筛选流程:
- 排序时高优先级的Tier1记录会自动排在低优先级记录前面,自动完成第一步的Tier1维度筛选
- 同Tier1的记录会自动按Tier2优先级排序,排在最前面的就是组内最高优先级的记录
# 按优先级升序排列(分类类型默认按定义的优先级顺序升序,高优先级记录排在最前) # 之后按ID分组取每组第一条 final_result = df.sort_values(by=['Tier1', 'Tier2'], ascending=True)\ .groupby('ID', as_index=False)\ .first()
运行后输出结果完全匹配预期:
| ID | Tier1 | Tier2 |
|---|---|---|
| 1111 | RF | B |
| 2222 | RF | B |
| 3333 | OK | B |
关于你最初的遍历写法的补充
如果你习惯用分组遍历的逻辑,也可以实现需求,只需要把每个分组筛选后的结果存入列表,最后用pd.concat()拼接所有分组结果即可,不需要手动操作原表:
grouped = df.groupby('ID') result_collector = [] for _, group in grouped: # 组内筛选最高优先级Tier1 highest_tier1 = group['Tier1'].max() group_tier1_filtered = group[group['Tier1'] == highest_tier1] # 组内同Tier1下筛选最高优先级Tier2 highest_tier2 = group_tier1_filtered['Tier2'].max() final_group = group_tier1_filtered[group_tier1_filtered['Tier2'] == highest_tier2] result_collector.append(final_group) # 拼接所有分组结果 final_result = pd.concat(result_collector, ignore_index=True)
注意:这种遍历写法在数据量超过10万行时,运行效率会远低于前面提到的排序+分组取首条的方案,更适合逻辑非常复杂、排序逻辑无法覆盖的特殊场景。
内容的提问来源于stack exchange,提问作者sdowling001
相关产品推荐
相关产品推荐

