Search code examples
matlabtimetime-seriescell-array

MATLAB: Sum rows into events per minute


In MATLAB (R2015b) I have this cell data from a large time-series:

'01-Jan-2017 09:01:48'    [ 5]
'01-Jan-2017 09:01:50'    [ 2]
'01-Jan-2017 09:01:51'    [12]
'01-Jan-2017 09:01:53'    [ 2]
'01-Jan-2017 09:01:56'    [ 1]
'01-Jan-2017 09:02:00'    [ 1]
'01-Jan-2017 09:02:01'    [ 2]
'01-Jan-2017 09:02:12'    [ 1]
'01-Jan-2017 09:02:17'    [ 2]
'01-Jan-2017 09:02:19'    [ 1]
'01-Jan-2017 09:02:21'    [ 4]
'01-Jan-2017 09:02:52'    [ 1]
'01-Jan-2017 09:03:00'    [ 1]
'01-Jan-2017 09:03:05'    [ 3]
'01-Jan-2017 09:03:23'    [ 2]
'01-Jan-2017 09:03:26'    [ 3]
'01-Jan-2017 09:03:36'    [ 3]
'01-Jan-2017 09:03:37'    [ 2]
'01-Jan-2017 09:03:38'    [ 1]
'01-Jan-2017 09:03:43'    [ 2]
'01-Jan-2017 09:03:49'    [ 2]
'01-Jan-2017 09:03:51'    [ 1]
'01-Jan-2017 09:03:55'    [ 1]

However, I would like to sum the rows into events per minute (instead of per second), i.e.

'01-Jan-2017 09:01:00'    [ 22]
'01-Jan-2017 09:02:00'    [ 12]
'01-Jan-2017 09:03:00'    [ 21]

How can I do this for my time-series?


Solution

  • You can use discretize combined with accumarray to sum up all values that occured in the same minute. First we have to convert the first column of date strings into datetime objects and then to perform the summation of the second column we convert it to a numeric array using [data{:,2}]

    % Convert the first column to datetime objects and discretize by minute
    [inds, edges] = discretize(datetime(data(:,1)), 'minute');
    
    % Sum all values from the same minute
    sums = accumarray(inds, [data{:,2}]);
    
    % Create the output cell array of date strings and sums
    result = [cellstr(datestr(edges(1:end-1))), num2cell(sums)];
    
    %   '01-Jan-2017 09:01:00'    [22]
    %   '01-Jan-2017 09:02:00'    [12]
    %   '01-Jan-2017 09:03:00'    [21]
    

    Update

    So it doesn't look like discretize works well with datetime objects in R2015b, but you could do something like the following where we break the dates into their components, remove the seconds, determine the unique groups and again use accumarray to perfom the summation

    % Break each date into it's components
    dv = datevec(data(:,1));
    
    % Set the seconds to 0 so that only minutes are considered
    dv(:,end) = 0;
    
    % Find the unique minutes
    [vals, ~, inds] = unique(dv, 'rows');
    
    % Sum up the value for each unique minute
    sums = accumarray(inds, [data{:,2}]);
    
    % Create the output cell array
    result = [cellstr(datestr(vals)), num2cell(sums)];