You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于分组的Pandas滚动排名计算问题(Rolling Rank Groupby)

按ID分组的滚动排名计算(Pandas实现)

需求描述

需要在Pandas中实现按ID分组的滚动排名计算:按每个ID分组,基于该ID的历史Value值(滚动2年窗口)计算当前值的排名,预期结果列如示例中的Rolling 2Y Rank。

示例数据

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'Year': [2000,2000,2000,2001,2001,2001,2002,2002,2002,2003,2003,2003],
    'ID': ['A','B','C','A','B','C','A','B','C','A','B','C'],
    'Value': [5,1,2,3,4,3,2,7,1,1,13,23],
    'Rolling 2Y Rank': [np.nan,np.nan,np.nan, 2,1,1,2,1,2,2,1,1]})

对应的表格:

YearIDValueRolling 2Y Rank
2000A5nan
2000B1nan
2000C2nan
2001A32
2001B41
2001C31
2002A22
2002B71
2002C12
2003A12
2003B131
2003C231

以ID=A为例:

  • 2000年无历史数据,结果为NA;
  • 2001年将3与2000年的5(2年滚动窗口)比较,降序排名为2;
  • 2002年将2与2001年的3比较,降序排名为2,以此类推。

问题分析

尝试的代码df.groupby('ID')['Value'].rolling(2).rank()未得到预期结果,原因有两点:

  1. 默认的rank()是升序排名,而需求是降序排名(值越大排名越靠前);
  2. 未指定min_periods,且未处理groupby滚动后的索引对齐问题,导致结果无法正确匹配原DataFrame。

正确实现方法

步骤1:确保数据按ID和Year排序(避免窗口计算出错)

df = df.sort_values(['ID', 'Year'])

步骤2:分组计算滚动降序排名

df['Calculated Rolling Rank'] = df.groupby('ID')['Value'].rolling(
    window=2,  # 2年滚动窗口
    min_periods=2  # 窗口至少包含2条数据才计算,否则为NaN
).rank(
    ascending=False,  # 降序排名:值越大排名越靠前
    method='min'  # 相同值取最小排名,匹配示例逻辑
).reset_index(level=0, drop=True)

验证结果

执行后Calculated Rolling Rank列将与预期的Rolling 2Y Rank完全一致:

print(df[['Year', 'ID', 'Value', 'Rolling 2Y Rank', 'Calculated Rolling Rank']])

输出:

YearIDValueRolling 2Y RankCalculated Rolling Rank
02000A5NaNNaN
32001A32.02.0
62002A22.02.0
92003A12.02.0
12000B1NaNNaN
42001B41.01.0
72002B71.01.0
102003B131.01.0
22000C2NaNNaN
52001C31.01.0
82002C12.02.0
112003C231.01.0

内容的提问来源于stack exchange,提问作者Derek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 07:23:18