Is there a simple way to reference months from data in matlab time?
3 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
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 comentario
Stephen23
el 7 de Jul. de 2015
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.
Respuestas (3)
David Young
el 7 de Jul. de 2015
Editada: David Young
el 7 de Jul. de 2015
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 comentarios
Stephen23
el 7 de Jul. de 2015
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 comentarios
Steven Lord
el 7 de Jul. de 2015
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 comentarios
Ver también
Categorías
Más información sobre Dates and Time en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!