2011-11-20 12 views
6

mam:W Clojure, co jest skutecznym sposobem, aby obliczyć średnią z wektorami całkowitych

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

Chcę uśrednić te (pierwiastek mądry, aby uzyskać):

[3 6 5 5 6] 

jak chcesz MATLAB:

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

z Incanter mogę zrobić:

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

Jeśli dane są raczej duże (i mam ich dużo), czy istnieje lepszy sposób na zrobienie tego?
Czy to pomaga wcześniej obliczyć wartość (count m)?
Czy to wcześniej pomoże defn z #(/ % (count m))?

Odpowiedz

4

Nie wiedząc, jak posługiwać się którymkolwiek z odlewów, oto jak można to zrobić "od zera".

(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

Dzięki @amalloy to działa, ale nie rozumiem, jak '(zastosować mapę (fn ...' działałoby, nie powinno być '(zastosować (map (fn ...'? – Ali

+1

@Ali No , stosujesz funkcję 'map' do sekwencji argumentów: konstruujemy anonimową funkcję, a następnie każdy element sekwencji' data'. 'map' jest skłonny zaakceptować argumenty" extra ", przekazując je do funkcja, na przykład '(mapa + [1 2] [10 20])' ~ = '[(+ 1 10) (+ 2 20)]'. – amalloy

7

Oto bardzo prosty i przejrzysty sposób to zrobić:

(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

Zapytałam siebie, czy (zastosuj + coll) byłaby bardziej wydajna następnie (zmniejszenie + coll). Już odpowiedział na http://stackoverflow.com/questions/3153396/clojure-reduce-vs-apply – NielsK

+0

Zmniejszenie jest bardzo nieznacznie szybciej (około 5-10% w nieformalnych testów właśnie zrobiłem) Ale to naprawdę zależy od osobistych preferencji - mam tendencję do myślenia w operacjach redukcji łatwiej niż w przypadku żonglerki parametrami. – mikera

6

Począwszy od 2013 roku, moje zalecenie byłoby po prostu użyć core.matrix.stats importować wszystkie te funkcjonalności:

(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 opiera się na interfejsie API core.matrix, więc będzie działał również na innych, bardziej zoptymalizowanych implementacjach wektorów i macierzy - prawdopodobnie będzie to lepsza opcja, jeśli robisz dużo ciężkich m przetwarzanie atrix.

Powiązane problemy