基于msgid去重pandas dataframe 按tr_flag及evid规则保留行的方案咨询
解决方案
SQL实现方案
你需要的规则完全可以通过SQL窗口函数的自定义排序逻辑实现,核心思路是对同一msgid分组下的所有行,按优先级排序后取排名第一的行即可,代码示例如下:
SELECT * FROM ( SELECT *, ROW_NUMBER() OVER ( PARTITION BY msgid ORDER BY tr_flag DESC, -- 优先排序tr_flag为True的行 CASE WHEN tr_flag = TRUE THEN evid END DESC, -- True行按evid倒序,取最大值 CASE WHEN tr_flag = FALSE THEN evid END ASC -- False行按evid正序,取最小值 ) AS rn FROM 你的表名 ) t WHERE rn = 1;
用你提供的示例数据执行后返回结果如下:
| Date | plid | evid | msgid | tr_type | tr_flag |
|---|---|---|---|---|---|
| 08-11-2021 | pl1 | 111 | msg1 | new | False |
| 08-11-2021 | pl1 | 555 | msg2 | new | True |
| 08-11-2021 | pl1 | 999 | msg3 | new | True |
完全符合你提出的三个规则要求。
Pandas原生实现方案
如果你是在Python环境处理DataFrame,也可以直接用pandas内置方法实现,效率比导出到SQL处理更高,代码示例如下:
import pandas as pd # 你的示例数据 data = [ ['08-11-2021', 'pl1', 111, 'msg1', 'new', False], ['08-11-2021', 'pl1', 222, 'msg1', 'new', False], ['08-11-2021', 'pl1', 333, 'msg1', 'new', False], ['08-11-2021', 'pl1', 444, 'msg2', 'new', False], ['08-11-2021', 'pl1', 555, 'msg2', 'new', True], ['08-11-2021', 'pl1', 666, 'msg2', 'new', False], ['08-11-2021', 'pl1', 777, 'msg3', 'new', True], ['08-11-2021', 'pl1', 888, 'msg3', 'new', True], ['08-11-2021', 'pl1', 999, 'msg3', 'new', True], ] df = pd.DataFrame(data, columns=['Date', 'plid', 'evid', 'msgid', 'tr_type', 'tr_flag']) # 核心去重逻辑 df['sort_key'] = df.apply(lambda row: (row['tr_flag'], row['evid'] if row['tr_flag'] else -row['evid']), axis=1) result = df.sort_values('sort_key', ascending=False).groupby('msgid', as_index=False).first().drop(columns='sort_key') print(result)
执行后输出结果和SQL方案一致。
内容的提问来源于stack exchange,提问作者GOPI M
相关产品推荐
相关产品推荐

