这里的问题似乎没有帮助:计算百分位数(Ruby)
我想从数字数组中计算第95个百分位数(或者任何其他想要的百分位数)。最终,这将应用于Rails中,以计算对许多记录的分布。
但是,如果我能确定如何从数字数组中准确地确定给定百分位数,我就可以从那里入手。
坦率地说,我很惊讶自己还没有找到某种宝石(gem)拥有这样的功能 - 我还没有找到。
非常感谢您的帮助。
这里的问题似乎没有帮助:计算百分位数(Ruby)
我想从数字数组中计算第95个百分位数(或者任何其他想要的百分位数)。最终,这将应用于Rails中,以计算对许多记录的分布。
但是,如果我能确定如何从数字数组中准确地确定给定百分位数,我就可以从那里入手。
坦率地说,我很惊讶自己还没有找到某种宝石(gem)拥有这样的功能 - 我还没有找到。
非常感谢您的帮助。
如果您想复制Excel的PERCENTILE函数,请尝试以下方法:
def percentile(values, percentile)
values_sorted = values.sort
k = (percentile*(values_sorted.length-1)+1).floor - 1
f = (percentile*(values_sorted.length-1)+1).modulo(1)
return values_sorted[k] + (f * (values_sorted[k+1] - values_sorted[k]))
end
values = [1, 2, 3, 4]
p = 0.95
puts percentile(values, p)
#=> 3.85
该公式基于QUARTILE方法,该方法实际上只是特定百分位数的计算方式 - https://support.microsoft.com/en-us/office/quartile-inc-function-1bbacc80-5075-42f1-aed6-47d735c4819d。
values
是否包含单个值,以便在这些情况下不会出错。
在我的情况下,我将以下内容添加到第一行:
return values.first if values.count == 1
- viktorsmaridescriptive_statistics
gem。
IRB 会话> require 'descriptive_statistics'
=> true
irb(main):009:0> data = [1, 2, 3, 4]
=> [1, 2, 3, 4]
irb(main):010:0> data.percentile(95)
=> 3.8499999999999996
irb(main):011:0> data.percentile(95).round(2)
=> 3.85
Gem 的好处之一在于其优雅地描述了“我想要数据的 95 百分位数”。
a = [1,2,3,4,5,6,10,11,12,13,14,15,20,30,40,50,60,61,91,99,120]
def percentile_by_count(array,percentile)
count = (array.length * (1.0-percentile)).floor
array.sort[-count..-1]
end
# 80th percentile (21 items*80% == 16.8 items are below; pick the top 4)
p percentile_by_count(a,0.8) #=> [61, 91, 99, 120]
def percentile_by_value(array,percentile)
min, max = array.minmax
range = max - min
min_value = (max-min)*percentile + min
array.select{ |v| v >= min_value }
end
# 80th percentile (119 * 80% = 95.2; pick values above this)
p percentile_by_value(a,0.8) #=> [99, 120]
有趣的是,Excel的PERCENTILE
函数返回80%分位数的第一个值为60
。如果您想要这个结果——如果您想要处于极限边缘的项目被包括在内——那么请将上面的.floor
更改为.ceil
。
percentile_by_count
有一个错误。[-0..-1]返回整个数组。尝试用你的解决方案计算百分位数0.999,你会看到这个问题。如果你进行这个编辑,它应该可以解决问题。(rem > 0)?sorted [-rem..-1]:[] - Amir这是我在自己的统计库中开发的方法:
def quantiles(data, probs=[0.25, 0.50, 0.75])
values = data.sort
probs.map do |prob|
h = 1 + (values.count - 1) * prob
mod = h % 1
(1 - mod) * values[h.floor - 1] + (mod) * values[h.ceil - 1]
end
end
quantiles(data, [0.95])
。该函数将返回数据的95%分位数。