How to aggregate rows in a matrix

6 views (last 30 days)
Carsten
Carsten on 2 Dec 2014
Edited: N00TN00t on 19 Jun 2017
If i have a matrix like the following example (or please see attached file)
2008,5,4,9,40,0,0.0,0.0,0.0,15.9
2008,5,4,9,41,0,0.0,0.0,1.0,16.3
2008,8,5,16,20,0,0.0,0.0,1.0,2.9
2008,8,5,16,21,0,0.0,0.0,1.0,2.9
and so on for a full year. The matrix represents year, month, date of month, hour, minute, zone1,zone2,zone3 and zone4 How can i create a program that takes an hour for example and aggregates zone1,zone2zone3 and zone4 for that full choose hour ? I have to end up with two vectors. One with year,month,date of month, hour, minute and one with the aggregated zone1,zone2,zone3,zone4 The original matrix consists of data for a Whole year. I was think of something with Unique but then i am not sure how i can aggregate the data!
I have use for example [day, ~, subs] = unique(m(:, 1:3), 'rows') Then i get all the days. Then i can use sumdayzone1 = accumarray(subs, m(:, 7), [], @sum) but that only gives me the sum of zone1 on the choosen day. How can i do all zone together so i end up with only one vector to the corrensponding day ? I am a total newbie in this so any kind of help would be nice, thanks
  1 Comment
Stephen23
Stephen23 on 2 Dec 2014
I can't find the file... can you attach it again, please?

Sign in to comment.

Accepted Answer

Guillaume
Guillaume on 2 Dec 2014
Edited: Guillaume on 4 Dec 2014
accumarray only operates on vectors, so you have no choice but to call it once per column:
[day, ~, subs] = unique(m(:, 1:3), 'rows');
colzones = [7 8 9 10];
sumdayzones = cell2mat(arrayfun(@(col) accumarray(subs, m(:, col), [], @sum), colzones, 'UniformOutput', false));
or with a loop
[day, ~, subs] = unique(m(:, 1:3), 'rows');
colzones = [7 8 9 10];
sumdayzones = zeros(size(day, 1), numel(colzones));
for colidx = 1:numel(colzones)
sumdayzones(:, colidx) = accumarray(subs, m(:, colzones(colidx)), [], @sum);
end
  8 Comments
Carsten
Carsten on 4 Dec 2014
I don't get that with concatenate it with the sums, sorry If i place it in the function the vector get 20 columns and it just looks really strange.
Guillaume
Guillaume on 4 Dec 2014
day returned by:
[day, ~, subs] = unique(m(:, 1:3), 'rows');
is only three columns. sumdayzones is only 4, therefore the concatenation is only 7 columns.

Sign in to comment.

More Answers (2)

Thorsten
Thorsten on 4 Dec 2014
[day, ~, subs] = unique(m(:, 1:3), 'rows');
zones_colind = [7:10];
for i = 1:size(day, 1)
m_day(i,:) = [day(i, :) sum(m(find(subs == i), zones_colind))];
end
  4 Comments
Carsten
Carsten on 4 Dec 2014
It might not make sense but that is what i have to do. Get to vectors one with the aggregated results and one vector with the starting point of the aggregation which is the first six columns
Thorsten
Thorsten on 4 Dec 2014
Like this?
[day, ~, subs] = unique(m(:, 1:3), 'rows');
zones_colind = [7:10];
for i = 1:size(day, 1)
ind = find(subs == i);
m_day(i,:) = [day(i, :) m(ind(1), 4:6) sum(m(ind, zones_colind))];
end

Sign in to comment.


N00TN00t
N00TN00t on 19 Jun 2017
Edited: N00TN00t on 19 Jun 2017
What if we want to aggregate the time vector, not the zones?
So for aggregating for the months, we want a matrix showing columns [1:6] of the original matrix, but each row showing only one month:
2008,1,0,0,0,0
2008,2,0,0,0,0
2008,3,0,0,0,0
2008,4,0,0,0,0
2008,5,0,0,0,0
2008,6,0,0,0,0
2008,7,0,0,0,0
2008,8,0,0,0,0
2008,9,0,0,0,0
2008,10,0,0,0,0
2008,11,0,0,0,0
2008,12,0,0,0,0

Categories

Find more on Programming in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!