如何找到Ruby数组/整数散列的异常值?

如何找到Ruby数组/整数散列的异常值?,ruby,math,statistics,boxplot,outliers,Ruby,Math,Statistics,Boxplot,Outliers,以下是我的意见: [{name: 'John', age: 50}, {name: 'Bob', age: 50}, {name: 'Paul', age: 0}, {name: 'Alfred', age: 100}] 我想找出极端年龄,我想能够把极端年龄作为一个变量,说明极端年龄应该有多合理。举个例子,我想找出10%的最极端值。例如,输出如下: # the extreme min values => [{name: 'Paul', age: 0}] # the extreme max

以下是我的意见:

[{name: 'John', age: 50}, {name: 'Bob', age: 50}, {name: 'Paul', age: 0}, {name: 'Alfred', age: 100}]
我想找出极端年龄,我想能够把极端年龄作为一个变量,说明极端年龄应该有多合理。举个例子,我想找出10%的最极端值。例如,输出如下:

# the extreme min values => [{name: 'Paul', age: 0}]
# the extreme max values => [{name: 'Alfred', age: 100}]
我该怎么做

我在网上找到了一些可能会有所帮助的资源,但老实说,我自己无法遵循这些例子:

这里有一种方法

1.对列表进行排序:

a = [{name: 'John', age: 50}, {name: 'Bob', age: 50}, {name: 'Paul', age: 0}, {name: 'Alfred', age: 100}]
a = a.sort{|a,b| a['age'] <=> b['age']}
请注意,这可能不是执行此操作的最有效方法,但对于小型阵列来说,这已经足够了

考虑到您的敏感性,上述方法的工作原理是将数组L的长度乘以产生L的百分比p,然后除以2,然后取元素

[0..l-1] 
作为较低的异常值和

[L-(l-1), L-1] 
作为你的上离群值

编辑:工作示例

L
是数组的长度,
p
是所需的异常值比率

l = (L*p)/2
对于p=0.2,L=20,我们需要四个异常值,两个在最小值,两个在最大值

l = (L*p)/2 = 2

min = a[0..1]
max = a[(L-(l-1), L-1] = a[(20-(2-1), 19] = a[19,19]

请注意,这表明我在上面告诉您的内容中存在错误-max可能应该是
a[(L-L),(L-1)]

此方法的起点是:

如果需要深入研究对象以确定其值,请使用:

class-Foo
读者:我
def初始化(i)
@i=i
结束
结束
minu|foo,max|foo=[1,3,0,9,6].map{n|foo.new(n)}.minmax|u by{foo | foo.i}
# => [#, #]

假设
arr
是您的哈希数组。您希望找到
n
数组中
arr[i][:age]
最大的值。您可以通过在
arr[i][:age]
上排序,然后获取最后的
n
元素来实现这一点。但是,如果
n
只是
arr.size
的一小部分,则查找和保存
arr[i][:age]
最大的一个可能会更快,请将其删除并重复
n-1

代码

def top_n(arr, n)
  ad = arr.dup
  n.times.with_object([]) do |_,a|
    j = ad.each_index.max_by { |i| ad[i][:age] }
    a << ad[j]
    ad.delete_at(j)
  end
end
arr = [{name: 'John'  , age:  50},
       {name: 'Bob'   , age:  50},
       {name: 'Tina'  , age:  80},
       {name: 'Paul'  , age:   0},
       {name: 'Alfred', age: 100}]

top_n(arr, 3)
  #=> [{:name=>"Alfred", :age=>100},
  #    {:name=>"Tina",   :age=>80},
  #    {:name=>"John",   :age=>50}]

对不起,我没听懂。能否添加一个示例,例如
[L-(L-1),L-1]
?@ChristofferJoergensen请参见上面的示例。但这只返回两个对象,最低和最高,对吗?我必须找到极限,例如10%,对。这是你做你需要的事情的基础,它不是一个完整的答案。你可以在这个基础上进一步发展。
class Foo
  attr_reader :i
  def initialize(i)
    @i = i
  end
end

min_foo, max_foo = [1, 3, 0, 9, 6].map{ |n| Foo.new(n) }.minmax_by{ |foo| foo.i }
# => [#<Foo:0x007fd6dc8630c0 @i=0>, #<Foo:0x007fd6dc863098 @i=9>]
def top_n(arr, n)
  ad = arr.dup
  n.times.with_object([]) do |_,a|
    j = ad.each_index.max_by { |i| ad[i][:age] }
    a << ad[j]
    ad.delete_at(j)
  end
end
arr = [{name: 'John'  , age:  50},
       {name: 'Bob'   , age:  50},
       {name: 'Tina'  , age:  80},
       {name: 'Paul'  , age:   0},
       {name: 'Alfred', age: 100}]

top_n(arr, 3)
  #=> [{:name=>"Alfred", :age=>100},
  #    {:name=>"Tina",   :age=>80},
  #    {:name=>"John",   :age=>50}]