首页 > 解决方案 > Proc Rank 替代 Python

问题描述

我有一个变量,其中包含从 1 到 321 的分数范围。当我在 SAS 中使用以下代码时。

proc rank data = test1 out = sorted groups =1000;
var score; ranks rank; run;

我得到如下所示的输出:


  score | rank
   1    | 3
   2    | 6
....
320     | 993
321     | 996

我正在尝试使用以下代码在 python 中复制相同的内容:

mylist= list(range(1,322))
test1 = pd.DataFrame({'score': mylist})
x = pd.qcut(test1.score, 1000, labels=False)

但我得到以下输出

0        0
1        3
...
319    996
320    999

正如您在上面看到的,在 python 中,分箱从零开始。有没有一种方法可以通过对我提到的 python 代码进行细微调整来在 python 中复制 SAS 的结果,或者任何其他方法也是首选的。

标签: pythonpandasdataframesas

解决方案


尝试这个:

function = lambda x: pd.Series(pd.qcut(x,1000,labels=False),index=x.index)
test1['ranks'] = test1.apply(function)

编辑 上面的解决方案确实不是你想要的。这是因为qcut解决方案不是 SAS 的副本proc rank,所以我回去看看proc rank实际做了什么。它也进行分组,这样做的公式是:

计算组值的公式如下:

FLOOR(rank*k/(n+1))

在哪里

  1. rank 是数据值的排名顺序
  2. k 是 GROUPS= 选项的值
  3. n 是非缺失值的数量

所以,我修改了方法:

mylist= list(range(1,322))
test1 = pd.DataFrame({'score': mylist})
test1['rank'] = test1['score'].rank()
test1['grouping'] = round(test1['rank']*(1000-1)/(len(test1['score'])+1))

排名第一,分组第二(Floor在 pandas 中是round)。这给出了注意!将len(test1['score'])被接管非空元素。另请注意,k-1. 在 SAS 中也是如此。

     score   rank  grouping
0        1    1.0       3.0
1        2    2.0       6.0
2        3    3.0       9.0
3        4    4.0      12.0
4        5    5.0      16.0
..     ...    ...       ...
316    317  317.0     983.0
317    318  318.0     987.0
318    319  319.0     990.0
319    320  320.0     993.0
320    321  321.0     996.0

[321 rows x 3 columns]

推荐阅读