基于多条件的GroupBy与Min/Max过滤:数据集去重需求
多条件数据集去重解决方案
原始数据集
ID Date Participant Source Col1 Col2 Col3 1 04/16/2010 3 2 1 0 1 1 04/16/2010 2 2 1 1 1 1 04/16/2010 2 1 0 0 1 2 10/16/2011 2 2 1 1 0 2 11/06/2008 2 1 2 2 1 2 11/06/2008 3 1 2 2 1 3 15/06/2005 3 2 0 1 1 3 15/06/2005 2 2 0 1 1
去重规则
- 当
Source≠2时:若Source、ID、Date三者相同,保留Participant值最小的行。 - 当
Source=2时:- 若
Source、ID、Date三者相同,且该ID没有其他Source值,保留Participant值最小的行。 - 若
Source、ID、Date三者相同,且该ID存在其他Source值,保留Participant值最大的行。
- 若
期望结果
ID Date Participant Source Col1 Col2 Col3 1 04/16/2010 3 2 1 0 1 1 04/16/2010 2 1 0 0 1 2 10/16/2011 2 2 1 1 0 2 11/06/2008 2 1 2 2 1 3 15/06/2005 2 2 0 1 1
实现代码(Python Pandas)
步骤1:导入库并构造数据集
import pandas as pd # 构造原始数据 data = { 'ID': [1,1,1,2,2,2,3,3], 'Date': ['04/16/2010','04/16/2010','04/16/2010','10/16/2011','11/06/2008','11/06/2008','15/06/2005','15/06/2005'], 'Participant': [3,2,2,2,2,3,3,2], 'Source': [2,2,1,2,1,1,2,2], 'Col1': [1,1,0,1,2,2,0,0], 'Col2': [0,1,0,1,2,2,1,1], 'Col3': [1,1,1,0,1,1,1,1] } df = pd.DataFrame(data)
步骤2:标记ID是否存在其他Source值
新增辅助列has_other_source,用于区分Source=2时的两种情况:
df['has_other_source'] = df.groupby('ID')['Source'].transform(lambda x: (x != 2).any())
步骤3:分组处理不同规则的行
处理Source≠2的行
按Source、ID、Date分组,保留Participant最小的行:
df_source_not2 = df[df['Source'] != 2].groupby(['Source', 'ID', 'Date'], as_index=False).apply( lambda x: x[x['Participant'] == x['Participant'].min()] ).reset_index(drop=True)
处理Source=2的行
分两种情况分别处理后合并:
df_source_2 = df[df['Source'] == 2].copy() # 情况1:ID无其他Source值,取Participant最小的行 case1 = df_source_2[df_source_2['has_other_source'] == False].groupby(['Source', 'ID', 'Date'], as_index=False).apply( lambda x: x[x['Participant'] == x['Participant'].min()] ).reset_index(drop=True) # 情况2:ID有其他Source值,取Participant最大的行 case2 = df_source_2[df_source_2['has_other_source'] == True].groupby(['Source', 'ID', 'Date'], as_index=False).apply( lambda x: x[x['Participant'] == x['Participant'].max()] ).reset_index(drop=True) # 合并两种情况 df_source_2_final = pd.concat([case1, case2], ignore_index=True)
步骤4:合并结果并整理
# 合并所有结果 final_df = pd.concat([df_source_not2, df_source_2_final], ignore_index=True) # 按ID、Date排序,还原逻辑顺序 final_df = final_df.sort_values(by=['ID', 'Date'], ascending=[True, False]).reset_index(drop=True) # 删除辅助列 final_df = final_df.drop('has_other_source', axis=1) # 打印结果 print(final_df)
运行后即可得到符合要求的去重数据集。
内容的提问来源于stack exchange,提问作者Ahir Bhairav Orai
相关产品推荐
相关产品推荐

