如何在Pandas DataFrame中去重并保留ans为yes的行?
处理重复ID的Pandas DataFrame:优先保留指定条件行
需求说明:
- 现有含重复
id列的Pandas DataFrame - 对每个重复
id,优先保留ans列值为"yes"的行 - 若该
id无"yes"值,则保留"no"值的行
示例数据
import pandas as pd data = { 'id': [1, 1, 2, 3, 4, 5, 5, 6, 7, 8, 8, 9, 9, 10], 'ans': ['no', 'yes', 'yes', 'no', 'no', 'yes', 'no', 'yes', 'no', 'no', 'yes', 'no', 'yes', 'no'] } df = pd.DataFrame(data)
解决方法
方法1:排序+去重(推荐,性能更优)
通过对ans列设置排序优先级,让"yes"排在同id组的最前面,再对id去重保留第一行:
# 按id升序、ans降序排序("yes"字典序大于"no",降序后排在前面) sorted_df = df.sort_values(['id', 'ans'], ascending=[True, False]) # 按id去重,保留每组第一行 df2 = sorted_df.drop_duplicates(subset='id').sort_index() # 输出结果 print(df2)
如果担心字典序的问题(比如后续ans值有变化),可以显式映射优先级:
# 给ans列设置优先级权重,yes为1,no为0 df['priority'] = df['ans'].map({'yes': 1, 'no': 0}) # 按id升序、priority降序排序 sorted_df = df.sort_values(['id', 'priority'], ascending=[True, False]) # 去重后删除辅助列并恢复原索引顺序 df2 = sorted_df.drop_duplicates(subset='id').drop('priority', axis=1).sort_index()
方法2:GroupBy+自定义函数
通过分组后自定义逻辑筛选目标行,逻辑更直观:
def select_preferred_row(group): # 优先返回含yes的行,否则返回no的行 if 'yes' in group['ans'].values: return group[group['ans'] == 'yes'].iloc[0] else: return group[group['ans'] == 'no'].iloc[0] # 按id分组并应用函数,重置索引 df2 = df.groupby('id').apply(select_preferred_row).reset_index(drop=True)
验证结果
两种方法最终输出的df2均符合预期:
# 输出内容: id ans 0 1 yes 1 2 yes 2 3 no 3 4 no 4 5 yes 5 6 yes 6 7 no 7 8 yes 8 9 yes 9 10 no
内容的提问来源于stack exchange,提问作者Stephen Okiya
相关产品推荐
相关产品推荐

