I have an array that is 13867 X 2 elements and stored in variable called "data". So, I want to do the following in Matlab:
- Average (row 1 -> row 21) ; i.e. take the average of first 21 elements
- Average (row 22 -> row 43) ; i.e. take the average of next 22 elements
- Average (row 44 -> row 64); i.e. take the average of the next 21 elements
- Average (row 65 -> row 86); i.e. take the average of the next 22 elements
- Repeat the process until the end of the matrix, so that we take the average of the last 21 elements from row 13847 to row 13876. I want the average of elements in column 1 and also column 2. I have somehow managed to do that in Excel, but it is a bit cumbersome task (had to create an index for the rows first). I guess at the end we will get 645 averages.
The key to doing that is inserting
NaN
rows to make the shorter blocks (21 rows) the same size as the longer blocks (22 rows). This is very easy, using theinsertrows
function from Matlab FileExchange:After that, row 22 will be
[NaN, NaN]
, row 66 will be[NaN, NaN]
, and so on. Now it gets very easy to calculate the mean. Simply reshape this matrix so that all values which should be averaged are on the same column. Finally, use thenanmean
function (mean function which simply ignoresNaN
) to get the result.It is not 100% clear to me, whether the result should be 645x2 or 645x1, i.e. whether to average over the rows as well, or not. Here would be the corresponding
reshape
's for both ways:1. Averaging over the rows too:
2. Leaving the rows alone:
Note that here, you'll need a final
squeeze
, as the result ofnanmean
would be of dimension1x645x2
, which is not very practical.squeeze
just removes this singleton dimension.Here's one way to solve it with some padding with
NaNs
, reshaping and concatenations -Verify output
First five rows -
Last row -
Explanation with the help of a toy example
Sample used -
1] Input :
2] Combine step-size :
3] Pad with NaN filled rows such that the number of rows is a multiple of
N
-4] This part might be a bit tricky. Consider each column from
Apad
is made into a 2D array, such that we would haveN
elements per column, because the intention here is to get averages along each column after further slicing each column into two subgroups of first three rows and rest four rows from such a 3D array. So, withApad
having 2 rows, we would have a 3D array with two 3D slices, such that the first 3D slice would be a reshaped version of first column inApad
i.e. ofApad(:,1)
. Similarly, the second 3D slice corresponds to the second column inApad
. Thus, the ressultant 3D array would be -5] Find mean/average along each column with
nanmean(..,1)
ignoring theNaNs
-6] Concatenate and reshape those averages into a 2D array -
7] Ignore NaN rows for final output -