Search code examples
matlabaccumarray

Summing data by window size in grouped data


I am quite new to matlab and I am trying to find a way to accomplish the following task without using for loops:

I have a data set looking like this:

data = [1 5; 1 3; 1 8; 2 1; 2 2; 2 5; 3 3; 3 8; 3 4]

the first column is a group (being a month year combination in the future)

Now I want to calculate a sum over the second column with a given window size but only if the group index is the same - if not the maximal sum in this group shall be calculated.

With window size=2 I would like to create the following result:

summed_data = [1 8; 1 11; 1 8; 2 3; 2 7; 2 5; 3 11; 3 12; 3 4]

With a window size of 3 the result would look like this:

summed_data = [1 16; 1 11; 1 8; 2 8; 2 7; 2 5; 3 15; 3 12; 3 4]

and so on.

I thought about using accumarray by creating sufficient subindexes - but I have a problem with the window size and that the sums are overlapping.

Has anyone an idea on how to implement it without using loops?

Thanks in advance and best regards stephan


Solution

  • This seems to work:

    ws = 2; k = [ones(ws,1);zeros(mod(ws,2),1)];
    C = accumarray(data(:,1),data(:,2),[],@(v){conv(v,k,'same')})
    

    You seem to be anchoring to the current pixel in the window and looking forward. Is that correct?

    Not sure if this covers all corner cases, but it might steer you in the right direction.

    Test: ws = 2

    ws = 2; k = [ones(ws,1);zeros(mod(ws,2),1)];
    C = accumarray(data(:,1),data(:,2),[],@(v){conv(v,k,'same')});
    summed_data = [data(:,1) vertcat(C{:})]
    summed_data =
    
         1     8
         1    11
         1     8
         2     3
         2     7
         2     5
         3    11
         3    12
         3     4
    

    Test: ws = 3

    summed_data = [data(:,1) vertcat(C{:})]
    summed_data =
    
         1    16
         1    11
         1     8
         2     8
         2     7
         2     5
         3    15
         3    12
         3     4