Pandas分组去重:保留组内指定列值为1的首行或任意行
解决DataFrame分组去重并优先保留特定行的问题
我来帮你搞定这个需求!这种「除某一列外其余值相同的行分组,优先保留该列为1的首行,无则留任意行」的场景,用Pandas可以轻松实现,我给你一步步拆解:
先看示例场景
咱们先造个贴近你需求的示例数据:
import pandas as pd df = pd.DataFrame({ 'col1': ['A', 'A', 'A', 'B', 'B', 'C', 'C'], 'col2': [10, 10, 10, 20, 20, 30, 30], 'flag': [0, 1, 0, 0, 0, 0, 1] })
期望输出是:
- A组(col1=A、col2=10)保留
flag=1的那行 - B组(col1=B、col2=20)随便保留一行
- C组(col1=C、col2=30)保留
flag=1的那行
核心解决方案
基础版:快速实现需求
思路很简单:先把flag=1的行排到每组的最前面,再按「除flag外的所有列」分组,取每组第一行即可:
# 1. 自动获取除flag外的所有列作为分组依据 group_cols = df.columns.difference(['flag']).tolist() # 2. 按flag降序排序,让1优先出现在前面;再分组取每组第一行 result = df.sort_values('flag', ascending=False).groupby(group_cols, as_index=False).first()
运行后得到的result就完全符合你的期望啦!
进阶版:保留原数据中第一个出现的flag=1行
如果你的需求里的「首行」是指原DataFrame中最早出现的flag=1行(而不是排序后的第一行),那可以给原数据加个原始索引,排序时兼顾索引顺序:
# 先给每行标记原始索引 df['original_idx'] = df.index # 排序规则:先按flag降序,再按原始索引升序(保证最早出现的1优先) result = df.sort_values(['flag', 'original_idx'], ascending=[False, True])\ .groupby(group_cols, as_index=False)\ .first()\ .drop('original_idx', axis=1) # 删掉临时加的索引列
这样就能确保分组内如果有多个flag=1的行,我们保留的是原数据里第一个出现的那行。
原理说明
sort_values通过降序排列flag,让所有符合条件(flag=1)的行优先出现在分组的顶部groupby(...).first()会取每组的第一行,刚好就是我们要保留的目标行;如果组内没有flag=1的行,就会保留原组里的任意一行(因为排序后都是0,不影响结果)
内容的提问来源于stack exchange,提问作者BallpointBen
相关产品推荐
相关产品推荐

