Reputation: 23
Say, for example, I have the following matrix:
[1 2 3 4 1 2 3 4
1 2 3 4 1 2 3 4
1 2 3 4 1 2 3 4]
How could I programmatically average together, say, every four columns so that I would end up with:
[2.5 2.5
2.5 2.5
2.5 2.5]
?
Thanks,
Tom
Upvotes: 2
Views: 236
Reputation: 112659
It can be done without loops using reshape
:
A = [1 2 3 4 1 2 3 4
1 2 3 4 1 2 3 4
1 2 3 4 1 2 3 4]; %// data matrix
N = 4; %// number of columns to average
result = squeeze(mean(reshape(A,size(A,1), N, []), 2));
If you have the Image Processing Toolbox, you can also use blockproc
:
result = blockproc(A, [size(A,1) N], @(x) mean(x.data, 2))
Upvotes: 3
Reputation: 221504
One approach based on sum
and reshape
-
reshape(sum(reshape(A,size(A,1),N,[]),2)/N,size(A,1),[])
Some benchmarks for the solutions posted thus far are presented here.
Benchmarking Code -
m = 1000; %// No. of rows in input
n = 4000; %// No. of cols in input
A = rand(m,n); %// Input with random data
N = 4; %// number of columns to average;
num_runs = 200; %// No. of iterations
disp('----------------- With sum+reshape');
tic
for k1 = 1:num_runs
out1 = reshape(sum(reshape(A,size(A,1),N,[]),2)/N,size(A,1),[]);
end
toc,clear out1
disp('----------------- With mean+reshape');
tic
for k1 = 1:num_runs
out2 = squeeze(mean(reshape(A,size(A,1), N, []), 2));
end
toc,clear out2
disp('----------------- With blockproc');
tic
for k1 = 1:num_runs
out3 = blockproc(A, [size(A,1) N], @(x) mean(x.data, 2));
end
toc,clear out3
disp('----------------- With filter');
tic
for k1 = 1:num_runs
B = filter(ones(1,N)/N,1,A,[],2);
out4 = B(:,N:N:end);
end
toc,clear out4 B
Results -
----------------- With sum+reshape
Elapsed time is 4.011844 seconds.
----------------- With mean+reshape
Elapsed time is 3.945733 seconds.
----------------- With blockproc
Elapsed time is 59.018457 seconds.
----------------- With filter
Elapsed time is 31.220875 seconds.
Upvotes: 3
Reputation: 25232
A simple approach would be abusing filter
:
A = [1 2 3 4 1 2 3 4 ;
1 2 3 4 1 2 3 4 ;
1 2 3 4 1 2 3 4 ]
N = 4;
B = filter(ones(1,N)/N,1,A,[],2)
C = B(:,N:N:end)
gives:
C =
2.5000 2.5000
2.5000 2.5000
2.5000 2.5000
which seems quite a bit faster than all that reshaping and squeezing action ;) Without proof though.
Upvotes: 2