2011-11-20 10 views
6

ho:In clojure, quello che è un modo efficace per calcolare la media dei vettori di interi

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

voglio media ci (elemento-saggio ottenere):

[3 6 5 5 6] 

come si farebbe in MATLAB:

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

Con Incanter posso fare:

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

Se i dati sono piuttosto grandi (e ne ho molti) c'è un modo migliore per farlo?
Aiuta a calcolare preventivamente lo (count m)?
Aiuta a defn il #(/ % (count m)) in anticipo?

risposta

4

Senza sapere come usare l'incanter, ecco come si potrebbe fare questo "da zero".

(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

Grazie @amalloy funziona, ma non capisco come '(applica la mappa (fn ...' funzionerebbe, non dovrebbe essere '(applica (mappa (fn ...'? – Ali

+1

@Ali No , stai applicando la funzione 'map' a una sequenza di argomenti: una funzione anonima che costruiamo, e quindi ogni elemento della sequenza' data'. 'map' è disposto ad accettare argomenti" extra ", passandoli a Per esempio, '(map + [1 2] [10 20])' ~ = '[(+ 1 10) (+ 2 20)]'. – amalloy

7

Ecco un modo piuttosto semplice e pulito per farlo:

(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

Chiesto a me stesso se (apply + coll) sarebbe più efficiente quindi (riduci + coll). Ho già risposto a http://stackoverflow.com/questions/3153396/clojure-reduce-vs-apply – NielsK

+0

Riduci leggermente più veloce (circa il 5-10% nei test informali che ho appena fatto) Ma è davvero una questione di preferenze personali - tendo a pensare alle operazioni di riduzione più facilmente di quanto faccio con la giocoleria parametrica. – mikera

6

Dal 2013, la mia raccomandazione sarebbe di utilizzare solo core.matrix.stats di importare tutte queste funzionalità:

(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 si basa sull'API core.matrix, quindi funzionerà anche su altre implementazioni più ottimizzate di vettori e matrici: è probabile che questa sia un'opzione migliore se si eseguono molte m pesanti elaborazione atrix.

Problemi correlati