Is there a simple way to reference months from data in matlab time?
조회 수: 4 (최근 30일)
이전 댓글 표시
I need to plot monthly averages for several years of data recorded every half hour for the entire year. I can specify months like this for each year, but is there a simpler way to do this? I need to do it for 5 years of data.
tm=data(:,1)+datenum(1904,1,1);
date=datevec(tm);
jan_96=find(tm>=datenum(1996,1,1) & tm<datenum(1996,2,1));
feb_96=find(tm>=datenum(1996,2,1) & tm<datenum(1996,3,1));
mar_96=find(tm>=datenum(1996,3,1) & tm<datenum(1996,4,1));
apr_96=find(tm>=datenum(1996,4,1) & tm<datenum(1996,5,1));
may_96=find(tm>=datenum(1996,5,1) & tm<datenum(1996,6,1));
jun_96=find(tm>=datenum(1996,6,1) & tm<datenum(1996,7,1));
jul_96=find(tm>=datenum(1996,7,1) & tm<datenum(1996,8,1));
aug_96=find(tm>=datenum(1996,8,1) & tm<datenum(1996,9,1));
sep_96=find(tm>=datenum(1996,9,1) & tm<datenum(1996,10,1));
oct_96=find(tm>=datenum(1996,10,1) & tm<datenum(1996,11,1));
nov_96=find(tm>=datenum(1996,11,1) & tm<datenum(1996,12,1));
dec_96=find(tm>=datenum(1996,12,1) & tm<=datenum(1996,12,31));
댓글 수: 1
Stephen23
2015년 7월 7일
Creating lots of variables like that is very awkward, because it mixes up meta-data with the code. It clutters your workspace, and makes writing, fixing and altering programs more difficult. It would be much cleaner and neater to create one variable that contains all of that information.
답변 (3개)
David Young
2015년 7월 7일
편집: David Young
2015년 7월 7일
Using the attached function, you can do this:
[isplit, ~, meantime] = splitTimes(tm, 'month'); % get start and end point of each month
for m = 1:size(isplit, 2)
meantemp(m) = mean( temp(isplit(1,m):isplit(2,m)) );
end
plot(meantime, meantemp);
datetick('x');
where temp is your input series of temperatures, the same length as tm, and meantime and meantemp are vectors of monthly means of observation time and temperature.
I haven't got your data so this isn't tested - let me know if you run into a problem.
댓글 수: 0
Stephen23
2015년 7월 7일
You do not provide any sample data for us to work with, which means we have to invent our own. Try this:
% Sample data and dates:
inp_date = [2010,10,5;2010,10,6;2010,10,7;2011,3,30;2011,3,31]
inp_data = 1:size(inp_date,1)
num_date = datenum(inp_date);
% Make range of months covering all sample dates:
min_max = datevec([min(num_date);max(num_date)]);
new_date(:,2) = min_max(1,2) + (0:12*diff(min_max(:,1))+min_max(2,2)-min_max(1,2)+1);
new_date(:,1) = min_max(1,1);
new_date(:,3) = 1;
new_num = datenum(new_date);
datevec(new_num) % <- just for demo, not required!
% Locate each date within one month:
min_max = bsxfun(@ge,num_date,new_num(1:end-1).') & bsxfun(@lt,num_date,new_num(2:end).');
[~,col] = find(min_max);
% Mean of data within each month:
out = accumarray(col,inp_data,[],@mean)
Which displays this in the command window:
inp_date =
2010 10 5
2010 10 6
2010 10 7
2011 3 30
2011 3 31
inp_data =
1 2 3 4 5
ans =
2010 10 1 0 0 0
2010 11 1 0 0 0
2010 12 1 0 0 0
2011 1 1 0 0 0
2011 2 1 0 0 0
2011 3 1 0 0 0
2011 4 1 0 0 0
out =
2.0000
0
0
0
0
4.5000
It has successfully grouped the values of inp_data according to the corresponding dates of inp_date, and calculated the means of each group.
댓글 수: 0
Steven Lord
2015년 7월 7일
I would use datetimes rather than serial date numbers.
% Let's start on January 1st of the current year
todayDate = datetime('today');
startDate = dateshift(todayDate, 'start', 'year');
% We want the last day of the current year
endDate = dateshift(todayDate, 'end', 'year');
% Generate a list of random days between startDate and endDate
randomDays = days(randi([0, days(endDate-startDate)], 10, 1))+startDate;
% Let's display them as day-month-year
randomDays.Format = 'dd-MMM-yyyy';
% In which month is each date located?
M = month(randomDays);
% Display the dates and the number of the month in which each occurs in a table
T = table(randomDays, M, 'VariableNames', {'Dates', 'MonthNumber'})
If you don't like the arithmetic involved in computing randomDays above, you could instead generate all the candidate days then select a subset (use RANDI to select with replacement, RANDPERM to select without replacement.)
allDays = (startDate:endDate).';
selection = randi(numel(allDays), 10, 1);
randomDays = allDays(selection);
댓글 수: 0
참고 항목
카테고리
Help Center 및 File Exchange에서 Dates and Time에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!