如何找到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}]