获取PostgreSQL percent_rank和scipy.stats.percentileofscore结果匹配

时间:2016-10-03 01:35:44

标签: python postgresql scipy rank percentile

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

PostgreSQL数据库中的计算使用percent_rank function,返回值列表中单个值的百分位数(从0到1)。在python脚本中,我使用的是Scipy percentileofscore function.

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

1 个答案:

答案 0 :(得分:2)

您可以使用scipy.stats.rankdata。以下示例再现了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]