如何遍历DataFrame并分组重复行,为分数列加序号实现去重?
解决方案
一、最简便的实现方法(无需手动循环分组)
直接用pandas的groupby()结合cumcount()对重复组内的行进行编号,批量修改score列即可,完全不用逐行处理:
- 确定重复行的判断依据:默认以
name+day+score完全重复为标准(如果你的重复逻辑不同,比如只看name和day,调整groupby的列参数即可)。 - 给每组重复行生成从1开始的序号。
- 仅对重复次数≥2的行,给
score添加(aN)后缀;非重复行保持原样。
示例代码:
import pandas as pd # 构造示例DataFrame df = pd.DataFrame({ 'name': ['Alice', 'Alice', 'Bob', 'Bob', 'Bob', 'Charlie'], 'day': ['2024-05-01', '2024-05-01', '2024-05-02', '2024-05-02', '2024-05-02', '2024-05-03'], 'score': ['90', '90', '85', '85', '85', '95'] }) # 按重复判断列分组,生成组内序号(从1开始) df['rank'] = df.groupby(['name', 'day', 'score']).cumcount() + 1 # 对重复行的score添加后缀,非重复行保留原值 df['score'] = df.apply( lambda x: f"{x['score']}(a{x['rank']})" if x['rank'] > 1 else x['score'], axis=1 ) # 可选:删除临时的rank列 df = df.drop('rank', axis=1) print(df)
运行结果:
name day score 0 Alice 2024-05-01 90 1 Alice 2024-05-01 90(a2) 2 Bob 2024-05-02 85 3 Bob 2024-05-02 85(a2) 4 Bob 2024-05-02 85(a3) 5 Charlie 2024-05-03 95
二、如果需要基于已识别的重复行分组处理
如果你已经通过df.duplicated()标记了重复行,可以筛选出重复组后再批量处理,避免无差别逐行循环:
# 标记所有重复行(包括第一次出现的行) df['is_duplicate'] = df.duplicated(['name', 'day', 'score'], keep=False) # 按重复组拆分,给每组内的行添加序号后缀 duplicate_groups = df[df['is_duplicate']].groupby(['name', 'day', 'score']) for group_key, group_df in duplicate_groups: for idx, row in group_df.iterrows(): # 计算当前行在组内的序号 rank = group_df[group_df.index <= idx].shape[0] if rank > 1: df.loc[idx, 'score'] = f"{row['score']}(a{rank})" # 删除临时标记列 df = df.drop('is_duplicate', axis=1)
关键注意点
- 重复判断逻辑:如果你的重复定义不是
name+day+score,比如只要name和day相同就算重复,只需要修改groupby和duplicated的列参数。 - 序号格式:如果需要给第一行也添加
(a1)后缀,把判断条件rank>1改成rank>=1即可。
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

