How can I sum every nth row?

If there's a matrix, for example:
A = [1 2 3 4 5 6 ; 1 3 5 7 9 11 ; 2 4 6 8 10 12]'
A =
1 1 2
2 3 4
3 5 6
4 7 8
5 9 10
6 11 12
7 13 14
I'm trying to sum 3 rows at a time (like an attached jpg file).
So I want to get:
B =
6 9 12
15 27 30
7 13 14
Thanks a lot!

2 Comments

Can you elaborate which row you want to sum in this example?
for example, in column 1 in A,
1+2+3= 6, 4+5+6= 15, and 7 doesn't have pairs so it's just 7.
Then column 1 in B goes 6, 15, 7.
Well.. I'm not sure this is enough.. Sorry for the late reply!

Sign in to comment.

 Accepted Answer

Paolo
Paolo on 8 Jul 2018
Edited: Paolo on 8 Jul 2018
A = [1 2 3 4 5 6 7; 1 3 5 7 9 11 13; 2 4 6 8 10 12 14]';
[n,col] = size(A);
index = 1:n;
elem = [repmat(3,1,floor(n/3))];
endv = n-sum(elem);
if(~endv)
endv = [];
end
index = mat2cell(index,1,[elem,endv])';
B = cell2mat(cellfun(@(x) sum(A(x,:),1),index,'un',0));
B =
6 9 12
15 27 30
7 13 14

6 Comments

Thanks!
but should I assign index every time when the size of the data varies?
If the data is big, then i need to make that index with another code, right?
How are indexes chosen?
um, i mean,
in your answer above, there's
index = {1:3;4:6;7}
if data i want to use has 7xn double form it always works,
but if data has 10x2 form, then I need to assign index as :
index = {1:3;4:6;7:9;10}
Thus, I have to change 'index' when the size of the data changes.
Am I getting right?
I've updated my answer.
Ohhhhh Thanks a lot!!!
You can say thank you to me and Stephen by accepting and voting for either one of the questions :)

Sign in to comment.

More Answers (2)

Peng Li
Peng Li on 13 Apr 2020
Edited: Peng Li on 13 Apr 2020
Just a comment that this could be done without involving a cell, which is the least type that I'd like to use among others.
A = [1 2 3 4 5 6 7; 1 3 5 7 9 11 13; 2 4 6 8 10 12 14]';
sumEveryRow = 3;
intBlock = floor(size(A, 1) / sumEveryRow)*sumEveryRow;
temp = reshape(A(1:intBlock, :)', size(A, 2), sumEveryRow, []);
sumA = [squeeze(sum(temp, 2))'; sum(A(intBlock+1:end, :), 1)];
This should be quick than the two above answers, both involving a cell type.
a test below
A = [1 2 3 4 5 6 7; 1 3 5 7 9 11 13; 2 4 6 8 10 12 14]';
A = repmat(A, 1000, 1);
tic
sumEveryRow = 3;
intBlock = floor(size(A, 1) / sumEveryRow)*sumEveryRow;
temp = reshape(A(1:intBlock, :)', size(A, 2), sumEveryRow, []);
sumA = [squeeze(sum(temp, 2))'; sum(A(intBlock+1:end, :), 1)];
toc
tic
[n,col] = size(A);
index = 1:n;
elem = [repmat(3,1,floor(n/3))];
endv = n-sum(elem);
if(~endv)
endv = [];
end
index = mat2cell(index,1,[elem,endv])';
B = cell2mat(cellfun(@(x) sum(A(x,:),1),index,'un',0));
toc
tic
N = 3;
S = size(A);
V = N*ones(1,ceil(S(1)/N));
V(end) = 1+mod(size(A,1)-1,3);
C = mat2cell(A,V,S(2));
Z = cellfun(@(m)sum(m,1),C,'uni',0);
toc
Elapsed time is 0.008036 seconds.
Elapsed time is 0.039083 seconds.
Elapsed time is 0.022779 seconds.
I repeated A 100 times to amphasize the effect of computational time.
A = [1 2 3 4 5 6 7; 1 3 5 7 9 11 13; 2 4 6 8 10 12 14]'
N = 3;
S = size(A);
V = N*ones(1,ceil(S(1)/N));
V(end) = 1+mod(size(A,1)-1,3);
C = mat2cell(A,V,S(2));
Z = cellfun(@(m)sum(m,1),C,'uni',0);
Giving
>> Z{:}
ans =
6 9 12
ans =
15 27 30
ans =
7 13 14

1 Comment

wow here's an another idea! Thank you!!

Sign in to comment.

Tags

Asked:

AJ
on 8 Jul 2018

Commented:

on 3 Oct 2022

Community Treasure Hunt

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

Start Hunting!