2016-08-03 3 views
0

관용구 방식으로 벡터의 가중 평균을 계산하고 싶습니다.Clojure : 벡터의 관용적 가중 평균

데이터 1 = [2 1] 중량 1 = 1 데이터 2 = 3 4], 중량 2 = 2

그럼 의미 = : 내가 원하는 것을 설명하기 위해, I는이 데이터가 상상 (2 * 1 + 3 * 2)/(1 + 2) (1 * 1 + 2 * 4)/(1 + 2) = [2.67 3.0 여기서

내 코드 :

(defn meanv 
    "Returns the vector that is the mean of input ones. 
    You can also pass weights just like apache-maths.stats/mean" 
    ([data] 
    (let [n (count (first data))] 
    (->> (for [i (range 0 n)] 
      (vec (map (i-partial nth i) data))) 
      (mapv stats/mean)))) 
    ([data weights] 
    (let [n (count (first data))] 
    (->> (for [i (range 0 n)] 
      (vec (map (i-partial nth i) data))) 
      (mapv (i-partial stats/mean weights)))))) 

다음

(meanv [[2 1] [3 4]] [1 2]) = [2.67 3.0] 

몇 가지 메모 :

stats/means은 1 또는 2 개의 입력을받습니다.
하나의 입력 버전에는 기본적으로 가중치 = 1이 있습니다.
두 개의 입력이 가중 버전입니다.

i-partial 부분처럼하지만 FN은 인수

Ex : ((partial/2) 1) = 2 
    ((i-partial/2) 1 = 1/2 

그래서 내 함수의 작동

, 아무 문제를 반대하고있다. 그러나 좀 더 관용적 인 Clojure에서 구현하고 싶습니다.

(map (fn [&xs ...과 같은 여러 조합을 시도했지만 작동하지 않습니다. 정의되지 않은 수의 벡터 중 n 번째 요소를 모두 가져 와서 stats/mean을 직접 적용 할 수 있습니까? 나는 한 줄을

감사를 의미

편집 (birdspider 응답)

(defn meanv 
    ([data] 
    (->> (apply mapv vector data) 
     (mapv stats/mean))) 
    ([data weights] 
    (->> (apply mapv vector data) 
     (mapv (i-partial stats/mean weights))))) 

그리고 당신이 원하는

(defn transpose [m] 
    (apply mapv vector m)) 

(defn meanv 
    ([data] 
    (->> (transpose data) 
     (mapv stats/mean))) 
    ([data weights] 
    (->> (transpose data) 
     (mapv (i-partial stats/mean weights))))) 
+0

왜 두 데이터가'(1 + 2) '로 나누어 져 있습니까? – birdspider

+0

nvm, 가중치로 나눈 값 – birdspider

+0

혼란 스럽네요 - 데이터가'[[2 1] [3 4]] '라고 쓰여진 텍스트 descr에서 당신이 사용하는 샘플에서의 무게는''[1 2]'입니다. '[[1 2] [3 4]]'- 그래서 어느 것이지? – birdspider

답변

0

우선으로는 (행렬을 전치하는 것입니다 초, 초, 삼 등을 얻음)

this SO 페이지를 참조하십시오.

; https://stackoverflow.com/a/10347404/2645347 
(defn transpose [m] 
    (apply mapv vector m)) 

다음과 같이 입력 확인은 완전히 부재합니다.

(defn meanv 
    ([data] 
    ; no weigths default to (1 1 1 ... 
    (meanv data (repeat (count data) 1)))) 
    ([data weigths] 
    (let [wf (mapv #(partial * %) weigths) ; vector of weight mult fns 
     wsum (reduce + weigths)] 
    (map-indexed 
     (fn [i datum] 
     (/ 
     ; map over datum apply corresponding weight-fn - then sum 
     (apply + (map-indexed #((wf %1) %2) datum)) 
     wsum)) 
     (transpose data))))) 

(meanv [[2 1] [3 4]] [1 2]) => (8/3 3) ; (2.6666 3.0) 

이익!

+0

답변 주셔서 감사합니다. 귀하의 논리가 까다로운 곳을 확인합니다. 평균 계산 작업을 수행했기 때문에 귀하의 게시물을 평가하기가 어렵습니다. 나는 그것을 mean-fn과 병합하여 더 나은지보기 위해 노력할 것입니다! –

+0

좋아, 분명히 그것을 시도!우리가 골프를 치고 있기 때문에 병합 –

1
(def mult-v (partial mapv *)) 
(def sum-v (partial reduce +)) 
(def transpose (partial apply mapv vector)) 

(defn meanv [data weights] 
    (->> data 
     transpose 
     (map (partial mult-v weights)) 
     (map sum-v) 
     (map #(/ % (sum-v weights))))) 
+0

'(지도 (comp f1 f2 f3))'로 내 게시물을 편집했습니다. – birdspider

+0

나는 골프를 의미하지는 않습니다. 이 문제를 해결하기 위해 내 버전을 제안했습니다. – OlegTheCat

+0

감사합니다. 방금 apache-maths 래퍼 인 의미로 내 fn을 사용했습니다. –

관련 문제