按分组及扩展DataFrame窗口计算跨序列值的百分位排名
分组扩展窗口下的百分位排名实现方案
原代码问题分析
- 误用全局数据集:原代码中
stats.percentileofscore(df['values'],1)调用的是整个DataFrame的values列,而非当前分组扩展窗口内的局部数据 - 未利用窗口参数:
expanding(1).apply()的lambda参数x代表当前窗口的分组数据,但原代码完全未使用该参数
正确实现代码
先导入所需依赖库:
import pandas as pd from scipy import stats
核心计算逻辑
针对分组后的values列应用扩展窗口,在每个窗口内计算目标值的百分位排名:
# 按Category分组,对values列执行扩展窗口计算 df['pct'] = df.groupby('Category')['values'].expanding(1).apply( lambda x: stats.percentileofscore(x, 1) ).reset_index(level=0, drop=True)
代码逐段解释
groupby('Category')['values']:按Category字段分组,仅选取需要计算的values列,缩小计算范围expanding(1):构建扩展窗口,每个窗口包含当前行及该分组下之前的所有行(窗口大小从1开始逐步扩大)apply(lambda x: stats.percentileofscore(x, 1)):对每个窗口内的values序列,计算目标值1的百分位排名(即该值在窗口数据中所处的百分比位置)reset_index(level=0, drop=True):移除分组产生的Category索引层,保持结果与原DataFrame的索引对齐
测试示例
构造测试数据验证效果:
# 测试数据 data = { 'Category': ['A', 'A', 'A', 'B', 'B', 'B'], 'values': [3, 1, 5, 2, 4, 1] } df = pd.DataFrame(data) # 执行计算 df['pct'] = df.groupby('Category')['values'].expanding(1).apply( lambda x: stats.percentileofscore(x, 1) ).reset_index(level=0, drop=True) print(df)
输出结果
Category values pct 0 A 3 100.000000 1 A 1 50.000000 2 A 5 33.333333 3 B 2 100.000000 4 B 4 100.000000 5 B 1 33.333333
结果说明:
- 分组A第2行:窗口数据为
[3,1],值1排在中间位置,对应百分位50% - 分组A第3行:窗口数据为
[3,1,5],值1是最小的,对应百分位约33.33%
内容的提问来源于stack exchange,提问作者greenguy
相关产品推荐
相关产品推荐

