2011-11-20 59 views
6

我:Clojure中,什麼是計算整數向量的平均的有效方式

(def data [[1 3 4 7 9] [7 6 3 2 7] [1 9 8 6 2]]) 

我要平均這些(元素方面獲得):

[3 6 5 5 6] 

像你這樣在MATLAB:

mean([1 3 4 7 9; 7 6 3 2 7; 1 9 8 6 2]) 

隨着咒術我可以這樣做:

(map #(/ % (count m)) (apply plus data)) 

如果數據相當大(我有很多)有沒有更好的方法來做到這一點?
事先計算(count m)有幫助嗎?
事先對defn#(/ % (count m))有幫助嗎?

回答

4

不知道如何使用任何incanter,這裏是如何做到「從頭開始」。

(let [data [[1 3 4 7 9] [7 6 3 2 7] [1 9 8 6 2]] 
     num (count data)] 
    (apply map (fn [& items] 
       (/ (apply + items) num)) 
     data)) 

;=> (3 6 5 5 6) 
+0

感謝@amalloy它的工作原理,但我不明白'(應用地圖(Fn ...'會起作用,不應該是'(apply(map(fn ...'? – Ali

+1

@Ali No ,你將'map'函數應用到一系列參數中:一個我們構造的匿名函數,然後'data'序列的每個元素'map'願意接受「額外」參數,將它們傳遞給例如,'(map + [1 2] [10 20])'〜='[(+ 1 10)(+ 2 20)]'。 – amalloy

7

這是一個非常乾淨和簡單的方式來做到這一點:

(def data [[1 3 4 7 9] [7 6 3 2 7] [1 9 8 6 2]]) 

(defn average [coll] 
    (/ (reduce + coll) (count coll))) 

(defn transpose [coll] 
    (apply map vector coll)) 

(map average (transpose data)) 
=> (3 6 5 5 6) 
+0

問自己是否(apply + coll)效率更高然後(減少+科爾)。已經在http://stackoverflow.com/questions/3153396/clojure-reduce-vs-apply回答 – NielsK

+0

減少速度稍快(在我剛做的非正式測試中約5-10%)但是這歸結於個人偏好 - 我傾向於比在參數雜耍中更容易地考慮減少操作。 – mikera

6

截至2013年,我的建議是隻使用core.matrix.stats導入所有這些功能:

(mean [[1 3 4 7 9] [7 6 3 2 7] [1 9 8 6 2]]) 
=> [3.0 6.0 5.0 5.0 6.0] 

core.matrix.stats構建在core.matrix API上,因此它也可以用於其他更優化的向量和矩陣實現 - 如果您正在執行大量重m,則這可能是更好的選擇atrix處理。