How can I average the first 14 columns, the second 14 columns, and so on and so forth?

2 views (last 30 days)
I have a matrix that is 533x54527 (rows x columns). I want to write a loop that takes the first 14 columns and averages across the columns. Then saves the new average into a new array. Then, I want to average the next 14 columns and append the new values into the initial new array (without using the 'append' command - it's not included in my toolbox).
How can I script it so that the last remaining columns (maybe 5 or 10) are also averaged (since 14 does not go into 54527 evenly)?
Thank you!
  2 Comments
the cyclist
the cyclist on 28 Feb 2019
I'm confused about one thing.
The first array of data to process will by 533x14. And you say you want the average across rows. My understanding of that phrase is that the result would be a 1x14 array.
But I'm guessing you actually want the average across columns, resulting in a 533x1 array for that step.
Can you please clarify?
Natasha D
Natasha D on 28 Feb 2019
Yes, you are correct - apologies for the confusion! Average across the columns, resulting in a 533x1 array.

Sign in to comment.

Accepted Answer

Geoff Hayes
Geoff Hayes on 28 Feb 2019
Natasha - so if you were to do this by hand, you would do something like
iteration column start column end
========= ============ ==========
1 1 14
2 15 28
3 29 42
etc.
So the column start increments by 14 each time. This will be the step size in a for loop. You could then check on each iteration to see if you have 14 columns to average...if not, then just use what is remaining.
Presumably, when you average across the rows, you will take the 533x14 matrix and reduce this to a 533x1 column. This means that you will - once all averages concatenated - have a 533xN matrix. To determine N you could do
N = floor(54527/14);
% if not evenly divisible by 14, then we need to add an extra column
if mod(54527,14) ~= 0
N = N + 1;
end
averageData = zeros(533, N);
We pre-allocate memory to averageData so that we can just update it on each iteration of the loop (rather than concatenating or appending the data).
Your code might then look like
stepSize = 14;
numColumns = 54527;
N = floor(numColumns/stepSize);
% if not evenly divisible by 14, then we need to add an extra column
if mod(numColumns,stepSize) ~= 0
N = N + 1;
end
averageData = zeros(533, N);
n = 1;
for k = 1:stepSize:numColumns
averageData(:, n) = mean(myData(:, k:min(k + stepSize - 1, numColumns)), 2);
n = n + 1;
end
We use min(k + 14 - 1, 54527) to determine the last column in our set to average and this handles the case where there are less than 14 columns remaining.

More Answers (2)

the cyclist
the cyclist on 28 Feb 2019
Assuming you actually want to average over columns (see my question above), I believe
out = movmean(M,[0 13],2);
out = out(:,1:14:end);
does what you want.
I didn't carefully check the result, so I may not have the indexing quite right, but you can definitely do what you want with the movmean command.

Jan
Jan on 28 Feb 2019
Edited: Jan on 28 Feb 2019
Reshape the data to blocks of the wanted width and calculate the average by mean or sum(X)/Width. Then append the mean over the trailing part on demand:
X = rand(533, 54527);
W = 14;
[S1, S2] = size(X);
Right = mod(S2, W);
Main = S2 - Right;
XX = reshape(X(:, 1:Main), S1, W, Main / W);
Y = reshape(sum(XX, 2) / W, S1, Main / W);
if Right ~= 0
Y = [Y, sum(X(:, Main + 1:S2), 2) / Right];
end

Categories

Find more on Matrices and Arrays in Help Center and File Exchange

Products


Release

R2017b

Community Treasure Hunt

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

Start Hunting!