如何在Pandas中基于自定义条件移除重复值并保留符合条件的行?
如何在Pandas去重时保留符合自定义条件的行
当然可以实现!咱先明确哈,drop_duplicates的keep参数确实不支持直接传自定义条件的索引——它只认'first'、'last'或者False这几个选项。不过别担心,有两种灵活的方式能达成你的需求,还能轻松扩展后续的多条件判断!
先拿你给出的示例DataFrame来演示:
import pandas as pd df = pd.DataFrame({ 'A': [1, 1], 'B': ['Hi', 'Bye'] })
方法一:排序优先法(适合简单条件)
思路是先给符合目标条件的行设置更高的优先级,让它们排在每组重复数据的最前面,再用drop_duplicates保留第一个行即可:
# 给行标记优先级:B='Hi'的行优先级为0(排前面),其他为1 df['priority'] = df['B'].map(lambda x: 0 if x == 'Hi' else 1) # 按分组键(A)+ 优先级排序,确保目标行在每组最前 df_sorted = df.sort_values(by=['A', 'priority']) # 去重后删掉临时的priority列 result = df_sorted.drop_duplicates(subset=['A'], keep='first').drop('priority', axis=1)
运行后result就是你要的保留B='Hi'的行:
| A | B |
|---|---|
| 1 | 'Hi' |
方法二:分组自定义筛选法(适合复杂多条件)
如果后续要加更复杂的判断逻辑,用groupby+自定义函数的方式会更灵活。你可以在函数里写任意多的条件判断,精准控制每组要保留的行:
def keep_target_row(group): # 先判断是否存在B='Hi'的行,存在就保留 hi_rows = group[group['B'] == 'Hi'] if not hi_rows.empty: return hi_rows # 这里可以继续加其他条件,比如: # elif not group[group['B'] == 'OtherTarget'].empty: # return group[group['B'] == 'OtherTarget'] # 兜底方案:如果没有符合条件的,保留组内第一行 else: return group.head(1) # 按分组键分组,应用自定义筛选函数 result = df.groupby('A', group_keys=False).apply(keep_target_row)
这种方法的优势在于,不管后续要加多少个判断条件,都可以直接在keep_target_row函数里扩展,完全满足你的灵活性需求。
为什么不能直接用keep=df.loc[...]?
drop_duplicates的keep参数设计上只接受字符串('first'/'last')或布尔值False,并不支持传入布尔数组或者索引对象,所以那种写法会直接报错。上面两种方法才是符合Pandas逻辑的正确实现方式。
内容的提问来源于stack exchange,提问作者alb
相关产品推荐
相关产品推荐

