Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sequence of a rolling average in Clojure

Tags:

clojure

I'm looking for an elegant way to generate a sequence of the rolling average of a sequence of numbers. Hopefully something more elegant than using lazy-seq

like image 804
Arthur Ulfeldt Avatar asked Dec 06 '22 03:12

Arthur Ulfeldt


2 Answers

Without any consideration of efficiency:

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

(defn moving-average [window lst] (map average (partition window 1 lst)))


user> (moving-average 5 '(1 2 3 4 5 6 7 8))
(3 4 5 6)

If you need it to be fast, there are some fairly obvious improvements to be made! But it will get less elegant.

like image 99
John Lawrence Aspden Avatar answered Jan 14 '23 13:01

John Lawrence Aspden


There's a very similar question on SO: Calculating the Moving Average of a List. It's more general -- a number of FP-friendly languages are represented, with the accepted answer using Scala -- but there are a few nice Clojure solutions.

I've posted my own solution over there. Note that it does use lazy-seq, but that's because I wanted it to perform well for large periods (which means adjusting the average at each step rather than calculating a separate average for each window of size = period into the input list). Look around that Q for nice solutions which made the other tradeoff, resulting in shorter code with a somewhat more declarative feel, which actually performs better for very short periods (although suffers significant slowdowns for longer periods, as is to be expected).

like image 40
Michał Marczyk Avatar answered Jan 14 '23 15:01

Michał Marczyk