Reputation: 3980
If I have one year worth of data
Jday = datenum('2010-01-01 00:00','yyyy-mm-dd HH:MM'):1/24:...
datenum('2010-12-31 23:00','yyyy-mm-dd HH:MM');
dat = rand(length(Jday),1);
and would like to calculate the monthly averages of 'dat', I would use:
% monthly averages
dateV = datevec(Jday);
[~,~,b] = unique(dateV(:,1:2),'rows');
monthly_av = accumarray(b,dat,[],@nanmean);
I would, however, like to calculate the monthly averages for the points that occur during the day i.e. between hours 6 and 18, how can this be done?
I can isolate the hours I wish to use in the monthly averages:
idx = dateV(:,4) >= 6 & dateV(:,4) <= 18;
and can then change 'b' to include only these points by:
b(double(idx) == 0) = 0;
and then calculate the averages by
monthly_av_new = accumarray(b,dat,[],@nanmean);
but this doesn't work because accumarray can only work with positive integers thus I get an error
Error using accumarray First input SUBS must contain positive integer subscripts.
What would be the best way of doing what I've outlined? Keep in mind that I do not want to alter the variable 'dat' when doing this i.e. remove some values from 'dat' prior to calculating the averages.
Thinking about it, would the best solution be
monthly_av = accumarray(b(idx),dat(idx),[],@nanmean);
Upvotes: 0
Views: 312
Reputation: 112659
You almost have it. Just use logical indexing with idx
in b
and in dat
:
monthly_av_new = accumarray(b(idx),dat(idx),[],@nanmean);
(and the line b(double(idx) == 0) = 0;
is no longer needed).
This way, b(idx)
contains only the indices corresponding to your desired hour interval, and data(idx)
contains the corresponding values.
EDIT: Now I see you already found the solution! Yes, I think it's the best approach.
Upvotes: 1