How to effectively get the mean for every three consecutive outputs?

28 views (last 30 days)
Hello, I have an array that is (21,7). I want to get the mean of every three rows from start to finish. For example, my results would output my dependent variable as [0 0 0 1 1 1 2 2 2] while my results/independent variable would be [2 3 2 9 8 7 17 21 16]. I would like to get a result where I get [0 1 2] and with the means [2.333 8 18]. Anyone have a code that would work for all of the columns in my array. I'm novice at MATLAB, so an easy to understand code would really help. If easier or more useful, if I could do the mean of the results for every dependent variable that was the same, that would work too (so I can avoid sorting next time). Thanks!

Accepted Answer

Guillaume
Guillaume on 11 Oct 2018
It would be useful if you used proper formatting in your question so we can see actual rows and columns.
Assuming the array
data = [1 10 19 28
2 11 20 29
3 12 21 30
4 13 22 31
5 14 23 32
6 15 24 33
7 16 25 34
8 17 26 35
9 18 27 36]
The mean of each block of 3 consecutive rows can be obtained by reshaping the matrix into a 3D arrays with 3 rows:
data3d = reshape(data, 3, [], size(data, 2))
Notice that the columns are now in the 3rd dimension. We can swap the dimensions to make taking the mean easier, by moving 1st dimension into 3rd, 3rd back to 2nd and 1st to second:
data3d = permute(data3d, [2 3 1])
Taking the mean across the pages, you get your result:
datamean3 = mean(data3d, 3)
Or as a one liner:
datamean3 = mean(permute(reshape(data, 3, [], size(data, 2)), [2 3 1]), 3)
  2 Comments
Stephen Zambrzycki
Stephen Zambrzycki on 11 Oct 2018
Thank you so much for the help!! It took me a while to conceptualize putting the data in a 3D format, but once I got that it worked really well. Thanks again!!
Guillaume
Guillaume on 12 Oct 2018
It's good that you understood. For this sorts of operation, moving one dimension up makes the processing easier, but yet, you do need to get your head around the dimension increase.
Note that reshape is a very cheap operation, the only thing it needs to do is change the header of the matrix to say that matrix has now 3 dimensions each of size x,y,z. On the other hand permute is expensive as it needs to swap around all the elements of the matrix.
For visualising what is happening I put the permute before the mean but if you're interested in efficiency, after the mean would be better. You just need to take the mean across a different dimension:
datamean3 = permute(mean(reshape(data, 3, [], size(data, 2)), 1), [2 3 1])

Sign in to comment.

More Answers (1)

Bruno Luong
Bruno Luong on 12 Oct 2018
If you want to avoid reshape, nd arrays, etc...
C = [zeros(1,size(A,2)); cumsum(A,1)];
M3 = diff(C(1:3:end,:),1,1)/3
That code will ignore the last trailing part in case length(A) is not divisible by 3.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!