2012-01-13 22 views
4

我有這個數組:從Ruby數組計算四分之一均值?

[288.563044, 329.835918, 578.622569, 712.359026, 866.614253, 890.066321, 1049.78037, 1070.29897, 2185.443662, 2492.245562, 4398.300227, 13953.264379] 

如何計算從這個interquartile mean

維基百科鏈接最好解釋它,但我基本上需要刪除底部和頂部的25%,只剩下中間的50%,其中我需要平均數字。

但是這是假設數組項的數量可以被4整除。Here's how to calculate it當它不能被4整除時。

那麼我該怎麼做呢?

+0

你有什麼特別的問題?鏈接的文章解釋了算法。 – 2012-01-13 20:22:10

+0

如何用Ruby實際實現它。 – Shpigford 2012-01-13 20:23:48

+2

到目前爲止你有什麼? – 2012-01-13 20:26:25

回答

4

這是一個數組的部分解決方案,它的數目是4的倍數。當我弄明白的時候,我會放一個完整的數組。

arr = [288.563044, 329.835918, 578.622569, 712.359026, 866.614253, 890.066321, 1049.78037, 1070.29897, 2185.443662, 2492.245562, 4398.300227, 13953.264379].sort! 
length = arr.size 
mean = arr.sort[(length/4)..-(length/4+1)].inject(:+)/(length/2) 

我認爲這是一個更好的解決方案。

def interquartile_mean(array) 
    arr = array.sort 
    length = arr.size 
    quart = (length/4.0).floor 
    fraction = 1-((length/4.0)-quart) 
    new_arr = arr[quart..-(quart + 1)] 
    (fraction*(new_arr[0]+new_arr[-1]) + new_arr[1..-2].inject(:+))/(length/2.0) 
end 
+0

由於您在修改後的數組上進行操作並返回結果,因此不需要再次使用該數組,因此不需要在此使用'sort'。此外,僅僅指出未來的參考,「Array#length」和「Array#size」(別名)比count更快。 :) – coreyward 2012-01-13 20:39:14

+0

謝謝!很高興知道。 – 2012-01-13 20:41:15

+0

雖然我不確定我會'排序!'一個不屬於該方法的數組。無論如何,我會+1,但這個問題讓我在兩個層面上感到失望。 – 2012-01-13 20:51:06

2

的簡單情況array_size mod 4 = 0

xs = [5, 8, 4, 38, 8, 6, 9, 7, 7, 3, 1, 6] 
q = xs.size/4 
ys = xs.sort[q...3*q] 
mean = ys.inject(0, :+)/ys.size.to_f 
#=> 6.5 

一般情況下(array_size >= 4):

xs = [1, 3, 5, 7, 9, 11, 13, 15, 17] 
q = xs.size/4.0 
ys = xs.sort[q.ceil-1..(3*q).floor] 
factor = q - (ys.size/2.0 - 1) 
mean = (ys[1...-1].inject(0, :+) + (ys[0] + ys[-1]) * factor)/(2*q) 
#=> 9.0 

但是,如果你不嘗試自己編寫它這將不利於很多...

1

托克蘭的答案的一個改進,增強了Array類和修復了一個邊界情況(方法如書面數組大小爲4)。

class Array 
    def interquartile_mean 
    a = sort 
    l = size 
    quart = (l.to_f/4).floor 
    t = a[quart..-(quart + 1)] 
    t.inject{ |s, e| s + e }.to_f/t.size 
    end 
end