索引非唯一时,如何获取Pandas DataFrame各日期的最大分值行?
解决Pandas中日期作为非唯一索引时,获取每日最高分对应行的问题
问题原因
当将Date设为DataFrame的非唯一索引后,groupby('Date')['Score'].idxmax()返回的是索引值(即日期时间戳),而非原始的行位置标签。由于同一日期对应多行数据,使用loc[idx]会匹配该日期下的所有行,导致结果不符合预期。
解决方案
方案1:用groupby(level)结合apply提取目标行
利用groupby(level='Date')按索引分组,通过apply在每个组内筛选出Score最高的行:
# Date已设为索引的情况下 result = all_data.groupby(level='Date').apply(lambda g: g.loc[g['Score'].idxmax()]) print(result)
输出结果:
Name Score Date 2022-01-01 John 92 2022-01-02 Mike 91 2022-01-03 Sally 96
方案2:排序后去重
先按Date升序、Score降序排序,再按Date去重保留每组第一行(即最高分的行):
# 排序:日期升序,分数降序 sorted_data = all_data.sort_values(['Score'], ascending=False).sort_index(ascending=True) # 按日期去重,保留第一个出现的行(即最高分) result = sorted_data.reset_index().drop_duplicates(subset='Date').set_index('Date') print(result)
方案3:用transform生成掩码筛选
通过transform计算每个日期组的最高分,再筛选出Score等于该值的行(若同一日期有多个相同最高分,会全部保留):
# 计算每个日期组的最高分 max_score_per_date = all_data.groupby(level='Date')['Score'].transform('max') # 筛选出分数等于组内最高分的行 result = all_data[all_data['Score'] == max_score_per_date] print(result)
额外技巧:设置索引时保留原始行索引
如果需要保留原始的整数行索引,可以在设置索引时添加drop=False,这样Date既是索引也是列,后续仍可沿用最初的idxmax方法:
# 设置索引时保留Date列 all_data = all_data.set_index('Date', drop=False) idx = all_data.groupby('Date')['Score'].idxmax() result = all_data.loc[idx] print(result)
内容的提问来源于stack exchange,提问作者frankd
相关产品推荐
相关产品推荐

