7
$\begingroup$

I am working in Mathematica. I have a table of 200 elements. I want to calculate the mean value for the first 20 elements, for the second 20 elements and so on, up to 200. I will get a table (matrix) of 10 elements. How I can solve this problem? Thanks for helping.

$\endgroup$
6
  • 4
    $\begingroup$ Your question is specific enough to have a proper title ;) And try Mean /@ Partition[data, 20] $\endgroup$
    – Öskå
    Apr 14, 2014 at 9:22
  • 2
    $\begingroup$ I'd like to reopen this as I think it has some value but I don't want to be heavy handed. Does anyone agree? $\endgroup$
    – Mr.Wizard
    May 30, 2014 at 9:26
  • $\begingroup$ @Mr.Wizard one agrees. But why not simply put it to the reopen vote? $\endgroup$
    – Yves Klett
    May 30, 2014 at 9:55
  • $\begingroup$ @Yves Thanks. As a moderator I cannot cast a "normal" reopen vote; it will directly reopen the Question. $\endgroup$
    – Mr.Wizard
    May 30, 2014 at 10:07
  • $\begingroup$ @Mr.Wizard - since your blockAverage2 is significantly faster than all other alternatives I tried it MUST be reopened! $\endgroup$
    – eldo
    May 30, 2014 at 10:08

4 Answers 4

15
$\begingroup$

As Öskå notes you can Partition your data and then Map Mean:

a = {q, r, s, t, u, v, w, x, y};

Mean /@ Partition[a, 3]
{1/3 (q + r + s), 1/3 (t + u + v), 1/3 (w + x + y)}

However if performance is a concern I propose using Total or Dot:

blockAverage1[a_List, n_Integer] := a ~Partition~ n ~Total~ {2} / n
blockAverage2[a_List, n_Integer] := Partition[a, n].ConstantArray[1/n, n]

Timings:

a = RandomReal[9, 5*^7]; (* big list *)

Mean /@ Partition[a, 20] // Timing // First
blockAverage1[a, 20]     // Timing // First
blockAverage2[a, 20]     // Timing // First
1.311

0.0654

0.0306

If you want averages of overlapping blocks see also:

Related:

$\endgroup$
8
$\begingroup$

In versions 10.2+ there is BlockMap:

a = {q, r, s, t, u, v, w, x, y};

BlockMap[Mean, a, 3]

{1/3 (q + r + s), 1/3 (t + u + v), 1/3 (w + x + y)}

Although this is much slower than the alternatives in Mr.Wizard's answer, its elegance may be of value since OP says

I have a table of 200 elements

Also, an undocumented 6-argument form of Partition:

Partition[a, 3, 3, None, {}, Mean[{##}] &]

{1/3 (q + r + s), 1/3 (t + u + v), 1/3 (w + x + y)}

$\endgroup$
1
$\begingroup$
list = {q, r, s, t, u, v, w, x, y};

Using SequenceCases (new in 10.1)

SequenceCases[list, x : {_, _, _} :> Mean @ x]

{(q + r + s)/3, (t + u + v)/3, (w + x + y)/3}

Generalization

SequenceCases[list, x : {Repeated[_, {2}]} :> Mean @ x]

{(q + r)/2, (s + t)/2, (u + v)/2, (w + x)/2}

$\endgroup$
1
$\begingroup$

Using SubsetCases:

list = {q, r, s, t, u, v, w, x, y};

SubsetCases[list, s : {_, _, _} :> Mean@s]

(*{1/3 (q + r + s), 1/3 (t + u + v), 1/3 (w + x + y)}*)

Or using SequenceSplit:

SequenceSplit[list, s : {_, _, _} :> Mean@s]

(*{1/3 (q + r + s), 1/3 (t + u + v), 1/3 (w + x + y)}*)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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