I want to build a loop with the following rules:
I have a list a={5,7,8,9,5,6,8,6,7,8}
. I want to print the mean of the first two {5,7}
. Then the mean of the first three {5,7,8}
, then the mean of the first four {5,7,8,9}
and on and on. Any ideas?
3 Answers
Here is a SparseArray
solution (as prompted by BlacKow):
vecs = Table[
SparseArray[ConstantArray[1/i, i], Length[a]], {i, 2, Length[a]}]
a.# & /@ vecs
-
1$\begingroup$ +1 for perverting
SparseArray
functionality into something that scales worse than my abacus... $\endgroup$– ciaoMay 20, 2016 at 23:24 -
$\begingroup$ @ciao Thanks! It was an interesting little challenge ... $\endgroup$ May 21, 2016 at 0:39
No need to loop, and in general you'll want to use built-in, functional idioms for readability and performance, e.g.:
Rest@Accumulate[a]/Range[2, Length@a]
will give the desired result efficiently.
-
$\begingroup$ In the case where one or more numbers have a weight, what can be done? For example, 5 has a weight 2 and 9 has a weight 4, the mean is estimated this way: (5*2+9*4) / (2+4) = 7.66. $\endgroup$– Roman SpMay 21, 2016 at 16:16
We should not try to hide that it can be done by indexing over a
, and since the OP specifically asked for such a solution, I think he deserves to get one. This is what occurred to me.
progressiveMean[a_List] :=
Module[{prev = a[[1]], next},
Rest @
Table[
next = (a[[i]] + (i - 1) prev)/i; prev = next,
{i, 2, Length[a]}]]
a = {5, 7, 8, 9, 5, 6, 8, 6, 7, 8};
progressiveMean[a] // N
{6., 6.66667, 7.25, 6.8, 6.66667, 6.85714, 6.75, 6.77778, 6.9}
This is essentially the procedural version of ciao's answer, but of course not so efficient.
Table[]
,Take[]
, andMean[]
. $\endgroup$FoldList
$\endgroup$SparseArray
solution for this one? :) $\endgroup$