【问题标题】:Find the percentile of a value查找值的百分位数
【发布时间】:2018-05-17 08:39:38
【问题描述】:

我有一个像[1,2,3,4,5] 这样的值数组,我需要找到每个值的百分位数。我期待的输出类似于[0,25,50,75,100]。

我在 numpy 中搜索了一个可以获得所需结果的 API,并找到了 np.percentile,但结果恰恰相反。给定一个百分位值,它将使用输入列表作为分布找到一个值。

有没有 api 或方法可以得到这个?谢谢

【问题讨论】:

  • 你的价值观似乎不对。不应该是[20.0, 40.0, 60.0, 80.0, 100.0]吗?
  • 那么,像这样,但是对于每个值? docs.scipy.org/doc/scipy/reference/generated/…
  • @Jean-FrançoisFabre 第零个百分位数应该是1,因为它是列表中的最小值,对吧?并且np.percentile(range(1,6),0) 返回了1。
  • @Jean-FrançoisFabre 使用 @Caramiriel 链接的函数,stats.percentileofscore([1, 2, 3, 4, 5], 3) 返回 60.0 但 np.percentile(range(1,6), 60.0) 返回 3.4。为什么会有差异?
  • np.percentile(range(0,6), 60.0) 返回 3。您的 1 值不被视为原点。 0 是原点。或者功能转移。我不是麻木的专家。 scipy 和 numpy 可能使用百分位事物的不同定义/实现。如果该功能不能满足您的要求,请不要使用它。

标签: python


【解决方案1】:

要在给定数据集中获取值的百分位数,请使用scipy's percentileofscore。

from scipy.stats import percentileofscore

dataset = [1,2,3,4,5]

percentile_of_3 = percentileofscore(dataset, 3)
print(percentile_of_3)

[Output] 60.0

此输出意味着数据集中 60% 的值小于或等于 3。 percentileofscore 的“kind”参数可用于指定百分位数的截止值是包含还是排除。例如:

percentile_of_3 = percentileofscore(dataset, 3)
print(percentile_of_3)

[Output] 40.0

表示数据集中 40% 的值小于 3。

如果我们想要一个包含每个值的百分位数的列表,我们可以使用列表推导:

all_percentiles = [percentileofscore(dataset, value, kind='strict') for value in dataset]

[Output] [0.0, 20.0, 40.0, 60.0, 80.0]

【讨论】:

    【解决方案2】:

    您应该使用list comprehension,将每个列表值除以max(lst) -1

    lst = [1,2,3,4,5]
    max_val = max(lst) -1
    lst = [(elem-1)/max_val * 100 for elem in lst]
    print(lst)
    

    输出

    [0.0, 25.0, 50.0, 75.0, 100.0]
    

    您也可以使用numpy 数组来实现此目的。

    arr = np.array([1,2,3,4,5])
    result = (arr - 1) / (np.max(arr) - 1) * 100
    

    【讨论】:

      【解决方案3】:

      如果您的输入可以包含要映射到 0% – 100% 的任意数字(例如 [3, 7, 13, 20]),那么您需要计算出最小数字和最大数字并将您的值扩展到 0 ... 100:

      values = [ 3, 7, 13, 20 ]
      min_value = min(values)
      max_value = max(values)
      for value in values:
        fraction = float(value - min_value) / (max_value - min_value)
        percentage = fraction * 100
        print(value, percentage)
      

      或者作为一种理解:

      percentiles = [ float(value - min_value) / (max_value - min_value) * 100
                      for value in values ]
      

      对于大型输入,也可以使用 numpy 加速:

      import numpy as np
      
      values = np.array([ 3, 7, 13, 20 ])
      min_value = values.min()
      max_value = values.max()
      percentiles = (values - min_value) / (max_value - min_value) * 100
      

      【讨论】:

        【解决方案4】:

        使用偏移量为 1 个值获取 0,计算最大值,减一,对其他值执行相同操作,计算列表理解中的百分比:

        lst = [1,2,3,4,5]
        maxval = max(lst)-1
        newlst = [(v-1)*100/maxval for v in lst]
        
        print(newlst)
        

        结果(作为浮点数,如果您需要整数,请使用// 进行除法)

        [0.0, 25.0, 50.0, 75.0, 100.0]
        

        【讨论】:

          【解决方案5】:

          我将百分位数的定义(来自维基百科)视为

          百分位的一个定义,通常在文本中给出,是 N 个有序值列表(从最小到最大排序)的第 P 个百分位 (0

          因此,对于您的数据,答案是:

          [20,40,60,80,100]
          

          我还假设您没有均匀分布,并且数字可以重复。您可以使用以下方法获取字典来查找结果:

          nbr = [1,1,3,4,5]
          sorted_nbr = sorted(nbr)
          ans = {x: 100*(1+i)/len(sorted_nbr) for i,x in enumerate(sorted_nbr)}
          

          这个产量:

          {1: 40.0, 3: 60.0, 4: 80.0, 5: 100.0}
          

          如果您需要该列表,请使用:

          [ans[x] for x in nbr]
          

          【讨论】:

            【解决方案6】:

            你应该使用np.true_divide。

            x = np.arange(5)
            np.true_divide(x, 4)*100
            [Output] array([ 0.  ,  25.,  50. ,  75.,  100.  ])
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2021-08-16
              • 1970-01-01
              • 2013-08-08
              • 1970-01-01
              • 2018-10-30
              • 2014-09-24
              • 2018-11-11
              • 1970-01-01
              相关资源
              最近更新 更多