在列中计算值的百分位数

22

我有一个数据框,其中有一列数值。这列数值不适合用正态分布进行近似。给定另一个不在此列中的数值,如何计算其在该列中的百分位?也就是说,如果该值大于该列中80%的值但小于其他20%,它将处于第20个百分位。


1
嘿,将被接受的答案更改为得票最高的答案会非常有用,因为它更完整,并且具有计算新值百分位数的更或多或少标准化方法。 - Philippe Fanaro
4个回答

43

要相对于数组(或在您的情况下是数据框列)找到值的百分位数,请使用scipy函数stats.percentileofscore()

例如,如果我们有一个值x(数据框中没有的其他数值),和一个参考数组arr(来自数据框的列),我们可以通过以下方式找到x的百分位数:

from scipy import stats
percentile = stats.percentileofscore(arr, x)
请注意,stats.percentileofscore()函数有一个第三个参数是 kind,它对百分位数结果有重大影响。您可以从 rankweakstrictmean 中进行选择。有关更多信息,请参见文档
以下是示例差异:
>>> df
   a
0  1
1  2
2  3
3  4
4  5

>>> stats.percentileofscore(df['a'], 4, kind='rank')
80.0

>>> stats.percentileofscore(df['a'], 4, kind='weak')
80.0

>>> stats.percentileofscore(df['a'], 4, kind='strict')
60.0

>>> stats.percentileofscore(df['a'], 4, kind='mean')
70.0
作为最后一点说明,如果您有一个比该列中其他值大80%的值,则它将处于80th百分位数(请参见上面的示例,了解kind方法如何在某种程度上影响此最终得分),而不是20th百分位数。有关更多信息,请参见此维基百科文章

5

可能已经很晚了,但仍然。

df['column_name'].describe()

将为您提供常规的25、50和75百分位数以及一些额外的数据,但如果您想要特定值的百分位数,则

df['column_name'].describe(percentiles=[0.1, 0.2, 0.3, 0.5])

这将给出第10、20、30和50个百分位数。您可以提供任意多的值。

生成的对象可以像字典一样访问:

desc = df['column_name'].describe(percentiles=[0.1, 0.2, 0.3, 0.5])
print(desc)
print(desc['10%'])

3

如果您正在寻找特定阈值上下的数值,则可以考虑使用pandas中的qcut函数。如果您想要小于20%和大于80%的值,请将数据分成5个大小相等的分区。每个分区都代表一个20%大小的“块”(五个20%分区为100%)。因此,假设您有一个DataFrame,其中包含1列名为'a'的数据:

df['newcol'] = pd.qcut(df['a'], 5, labels=False)

这将为您的DataFrame添加一个新列,每行都有一个值在(0、1、2、3、4)之间。其中,0表示最低20%,4表示最高的20%,即80%百分位数。


1

对列进行排序,查看值是否在前20%或任何百分位数中。

例如:

def in_percentile(my_series, val, perc=0.2): 
    myList=sorted(my_series.values.tolist())
    l=len(myList)
    return val>myList[int(l*perc)]

或者,如果您想要实际的百分位数,只需使用searchsorted

my_series.values.searchsorted(val)/len(my_series)*100

这样,我必须迭代所有可能的百分位数,以找出新值所在的百分位数。 - Bluefire
请注意,使用searchsorted()函数将无法提供准确的结果。对于处于94.5%百分位数的值,我得到的是"100"。 - Enrique Ortiz Casillas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接