使 PostgreSQL percent_rank 和 scipy.stats.percentileofscore 结果匹配

Getting PostgreSQL percent_rank and scipy.stats.percentileofscore results to match

我正在尝试对在 PostgreSQL 数据库中完成的计算结果进行 QAQC,使用 python 脚本读取计算的输入并回显计算步骤并比较最终结果python 脚本针对 PostgreSQL 计算的结果。

PostgreSQL 数据库中的计算使用 percent_rank function, returning the percentile rank (from 0 to 1) of a single value in a list of values. In the python script I am using the Scipy percentileofscore function.

所以,问题是:我无法获得匹配的结果,我想知道是否有人知道我应该在 Scipy percentileofscore 函数中使用什么设置来匹配 PostgreSQL percent_rank 函数。

您可以使用 scipy.stats.rankdata. The following example reproduces the result shown at http://docs.aws.amazon.com/redshift/latest/dg/r_WF_PERCENT_RANK.html:

In [12]: import numpy as np

In [13]: from scipy.stats import rankdata

In [14]: values = np.array([15, 20, 20, 20, 30, 30, 40])

rankdata(values, method='min') 给出所需的排名:

In [15]: rank = rankdata(values, method='min')

In [16]: rank
Out[16]: array([1, 2, 2, 2, 5, 5, 7])

然后基本计算得出等同于 percent_rank:

In [17]: (rank - 1) / (len(values) - 1)
Out[17]: 
array([ 0.        ,  0.16666667,  0.16666667,  0.16666667,  0.66666667,
        0.66666667,  1.        ])

(我正在使用 Python 3.5。在 Python 2 中,使用类似 (rank - 1) / float(len(values) - 1) 的东西。)


您可以使用 percentileofscore,但是:

  • 您必须使用参数 kind='strict'
  • 您必须按 n/(n-1) 缩放结果,其中 n 是值的数量。
  • 您必须除以 100 才能将真正的百分比转换为 0 到 1 之间的分数。
  • percentileofscore 期望它的第二个参数是一个标量,所以你必须使用循环来分别计算每个值的结果。

下面是一个使用与上述相同值的示例:

In [87]: import numpy as np

In [88]: from scipy.stats import percentileofscore

In [89]: values = np.array([15, 20, 20, 20, 30, 30, 40])

In [90]: n = len(values)

这里我使用列表理解来生成结果:

In [91]: [n*percentileofscore(values, val, kind='strict')/100/(n-1) for val in values]
Out[91]: 
[0.0,
 0.16666666666666666,
 0.16666666666666666,
 0.16666666666666666,
 0.66666666666666663,
 0.66666666666666663,
 1.0]