Asked by Natasha D
on 28 Feb 2019

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!

Answer by Geoff Hayes
on 28 Feb 2019

Accepted Answer

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.

Sign in to comment.

Answer by 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.

Answer by Jan
on 28 Feb 2019

Edited by 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

Sign in to comment.

Opportunities for recent engineering grads.

Apply Today
## 2 Comments

## the cyclist (view profile)

Direct link to this comment:https://de.mathworks.com/matlabcentral/answers/447501-how-can-i-average-the-first-14-columns-the-second-14-columns-and-so-on-and-so-forth#comment_676149

## Natasha D (view profile)

Direct link to this comment:https://de.mathworks.com/matlabcentral/answers/447501-how-can-i-average-the-first-14-columns-the-second-14-columns-and-so-on-and-so-forth#comment_676180

Sign in to comment.