在Pandas中按年份分组提取Top N最高评分数据的问题求助
解决Pandas Groupby+Nlargest无法返回完整行数据的问题
嘿,我来帮你搞定这个问题!你遇到的核心问题是在groupby之后只选择了特定列,导致nlargest只能返回这些列的数据,而不是完整的行记录。下面我给你两种靠谱的解决方案,还会解释你原来代码的问题所在。
问题分析
你原来的代码:
v=style.groupby(by='review_year')['beer_style']['review_overall'].nlargest(3)
这里你在groupby之后链式选择了['beer_style']['review_overall'],相当于只告诉Pandas要处理这两列,自然返回的结果里只有这两个相关列,丢失了其他行数据。我们需要让groupby对整个子DataFrame操作,才能保留完整行。
解决方案1:Groupby + Apply + Nlargest(直观易读)
这种方法直接对每个分组的子DataFrame调用nlargest,保留所有列数据:
import pandas as pd # 先构造你的示例数据(对应你给出的列名) data = { 'style': ['a', 'b', 'c'], 'year': [1990, 1990, 1990], 'review_score': [4.0, 5.0, 4.2] } df = pd.DataFrame(data) # 按year分组,每组取review_score最高的前2条完整记录 top_records = df.groupby('year').apply(lambda x: x.nlargest(2, 'review_score')).reset_index(drop=True) print(top_records)
运行后输出完全符合你的期望:
| style | year | review_score |
|---|---|---|
| b | 1990 | 5.0 |
| c | 1990 | 4.2 |
apply(lambda x: x.nlargest(2, 'review_score')):对每个分组的子DataFramex,按review_score降序取前2行reset_index(drop=True):去掉groupby生成的多级索引,得到干净的结果
解决方案2:Sort + Groupby + Head(性能更优)
如果你的数据集很大,这种方法比apply更高效,因为Pandas的排序和head操作是经过优化的:
# 先按year升序、review_score降序排序 sorted_df = df.sort_values(['year', 'review_score'], ascending=[True, False]) # 按year分组,取每组前2条 top_records = sorted_df.groupby('year').head(2).reset_index(drop=True) print(top_records)
输出和上面完全一致,这种方法的优势是避免了apply的循环操作,处理百万级数据时速度更快。
注意事项
- 确保你的列名和代码里一致:你示例里的列是
style/year/review_score,但代码里写的是review_year/beer_style/review_overall,记得替换成你实际的列名哦! - 如果有多个记录评分相同,
nlargest会保留所有并列的行,如果你需要严格取TopN,可以结合drop_duplicates或者调整排序规则。
内容的提问来源于stack exchange,提问作者SrihariRaghu
相关产品推荐
相关产品推荐

