1
$\begingroup$

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?

$\endgroup$
5
  • $\begingroup$ Use Table[], Take[], and Mean[]. $\endgroup$ May 20, 2016 at 18:25
  • 2
    $\begingroup$ Related/duplicate: Alternatives to procedural loops and iterating over lists in Mathematica $\endgroup$
    – rm -rf
    May 20, 2016 at 18:26
  • 4
    $\begingroup$ It doesn't matter for your particular case, but if the list is long enough, you want to make sure that you are not recalculating sum of all numbers at every iteration. So you can figure out a recursive relation for your mean values and then use FoldList $\endgroup$
    – BlacKow
    May 20, 2016 at 18:41
  • $\begingroup$ @J.M. Are you planning to come up with SparseArray solution for this one? :) $\endgroup$
    – BlacKow
    May 20, 2016 at 20:26
  • $\begingroup$ @BlacKow, for sure, I never would have deigned to post Anton's solution… ;P $\endgroup$ May 21, 2016 at 4:52

3 Answers 3

3
$\begingroup$

Here is a SparseArray solution (as prompted by BlacKow):

vecs = Table[
  SparseArray[ConstantArray[1/i, i], Length[a]], {i, 2, Length[a]}]

a.# & /@ vecs
$\endgroup$
2
  • 1
    $\begingroup$ +1 for perverting SparseArray functionality into something that scales worse than my abacus... $\endgroup$
    – ciao
    May 20, 2016 at 23:24
  • $\begingroup$ @ciao Thanks! It was an interesting little challenge ... $\endgroup$ May 21, 2016 at 0:39
6
$\begingroup$

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.

$\endgroup$
1
  • $\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 Sp
    May 21, 2016 at 16:16
1
$\begingroup$

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.

$\endgroup$

Not the answer you're looking for? Browse other questions tagged or ask your own question.