基于条件对Pandas DataFrame分组并过滤重复项
我来帮你搞定这个Pandas分组过滤的问题~先确认下你的数据结构,你已经把ID设为索引,Date转成了 datetime 类型,接下来根据不同的过滤需求,我给你几种实用的解决方案:
场景1:去除同一ID下type+source完全重复的行
如果你的目标是删掉同一个ID里,type和source都一模一样的重复行(比如同一ID下有两行type=yes且source=1,只留一行),有两种简单方法:
方法1:直接用drop_duplicates快速去重
# 指定按type和source去重,保留第一次出现的行,你也可以改成keep='last'保留最后一行 df_filtered = df.drop_duplicates(subset=['type', 'source'], keep='first')
方法2:用groupby聚合实现
# 按ID、type、source分组,取每组的第一行(也可以用last()、max()等聚合函数) df_filtered = df.groupby(['ID', 'type', 'source']).first().reset_index().set_index('ID')
场景2:按ID分组,根据type应用不同过滤规则
比如想给type=yes和type=no的组分别设置规则:
- 对
type=yes的ID,只保留日期最新的一行 - 对
type=no的ID,保留所有source不重复的行
可以用groupby+自定义函数实现:
def filter_single_group(group): # 每个组里的type都是相同的,取第一个判断即可 if group['type'].iloc[0] == 'yes': # 筛选出日期最大(最新)的行 return group[group['Date'] == group['Date'].max()] elif group['type'].iloc[0] == 'no': # 去掉source重复的行 return group.drop_duplicates(subset='source') # 按ID分组后应用自定义过滤函数,最后重置索引 df_filtered = df.groupby('ID').apply(filter_single_group).reset_index(drop=True).set_index('ID')
运行后得到的结果是:
Date source type ID 1 2001-01-01 3 yes 2 2010-01-01 1 yes 3 2000-01-01 2 no 4 2001-01-01 2 no 4 2000-01-01 1 no
场景3:按ID+type分组,保留每组内source唯一的所有行
如果想确保每个(ID+type)组合里,source没有重复值,同时保留所有不同source的行(和你给出的处理后DataFrame一致,因为你的原始数据里本来就没有重复的source),可以这么写:
df_filtered = df.groupby(['ID', 'type']).apply(lambda x: x.drop_duplicates(subset='source')).reset_index(drop=True).set_index('ID')
场景4:按ID分组,保留每组内日期最新的N行
比如每个ID只保留日期最新的1行:
# 先按日期降序排序,再取每组的第一行 df_filtered = df.groupby('ID').apply(lambda x: x.sort_values('Date', ascending=False).head(1)).reset_index(drop=True).set_index('ID')
如果你的需求是其他特定条件,可以再补充说明细节~
内容的提问来源于stack exchange,提问作者It_is_Chris
相关产品推荐
相关产品推荐

