# Calculate mean of every 4 elements in a row for an array

3 views (last 30 days)
Felix Blum on 22 Feb 2020
Commented: Image Analyst on 22 Feb 2020
I have a 35040x60 array and want to calculate the average of every 4 values, so that I get a 35040x15 array.
My code so far:
target=[];
for i=1:35040
target=[target; mean(reshape(matrix(i,:)',4,[]))];
end
However, as you can imagine, the performance is horrible.
How to improve it?

Matt J on 22 Feb 2020
Edited: Matt J on 22 Feb 2020
result = sepblockfun(yourMatrix,[1,4],'mean');

Image Analyst on 22 Feb 2020
Try conv():
m = randi(9, 35040,60); % Create random sample data
kernel = ones(1, 4)/4; % Kernel to get mean over 4 elments
tic
theMeans = conv2(m, kernel, 'valid'); % Convolve to get means.
theMeans = theMeans(:, 1:4:end); % Subsample
toc
The time is:
Elapsed time is 0.036778 seconds.

Matt J on 22 Feb 2020
sepblockfun will be faster, particularly for large data sets. Compare:
m = randi(9, 350400,120); % Create random sample data
kernel = ones(1, 4)/4; % Kernel to get mean over 4 elments
tic
theMeans = conv2(m, kernel, 'valid'); % Convolve to get means.
theMeans1 = theMeans(:, 1:4:end); % Subsample
toc
%Elapsed time is 0.252221 seconds.
tic
theMeans2 = sepblockfun(m,[1,4],'mean');
toc
%Elapsed time is 0.146145 seconds.
Image Analyst on 22 Feb 2020
True, but I thought I'd offer a built-in solution rather than a third party solution. However conv2() does do a bunch of computations that ultimately get thrown out. But it is simple, though at the cost of 10 milliseconds for data ten times as large as what he said he had. There is another built-in function that can do it faster and more efficiently than conv2() and that function is blockproc(). In case he's interested, I've attached some general purpose demos for blockproc().