日付/時刻に行うための操作が多数ある場合、私はあなたパフォーマンスをしたい、私はdatenum
の使用を検討することを勧めます。この形式では、各時刻/日付は単なる数値に過ぎず、複雑なオブジェクト(例えば、datetime
)を扱わなければならない場合よりも高速な計算が可能です。
計算量が多い場合は、いつでもdatetime
オブジェクトに変換できます。
ここでは、あなたの例と同じ日付ベクトルを生成する(より速く)方法があります。理解すべき主な機能は、datenum
とbsxfun
です。
私はそれぞれの行を作成したので少し分かりやすく、一時的な変数を使用して分かりやすく表示しています。
%% Create the vector of days
% Initial parameters
StartDate = datenum(1991,11,01) ; % first day
nDaysFromStart = 60 ; % number of days
EndDate = StartDate + nDaysFromStart ; % last day to consider
dowStart = weekday(StartDate) ; % "day of week" number
dowEnd = weekday(EndDate) ;
% now create an array containing an integer multiple of 7 (days)
daysarray = (0-dowStart+1):(nDaysFromStart+7-dowEnd) ;
% reshape it [7xN] to trim the days of the week we don't want
daysarray = reshape(daysarray,7,[]) ;
dowToRemove = [1 7] ; % remove Sunday (1) and Saturday (7)
daysarray(dowToRemove,:) = [] ;
% Now remove the extra days created at start and end. Note that this
% operation will also reshape the 2d array into a 1d vector.
daysarray(daysarray<0 | daysarray>nDaysFromStart) = [] ;
% Now add the real start date to all elements of the vector
daysarray = daysarray + StartDate ;
%% Create the vector of minutes for any given day
step = 1/24/60 ; % portion of a day that represent a minute
start = datenum(0,0,0,8,30,0) ; % start time for each day
stop = datenum(0,0,0,15,00,00) ;% end time for each day
dailyvec = (start:step:stop).' ;
%% Use bsxfun to create the complete arrays
alldates = bsxfun(@plus,daysarray,dailyvec) ;
%% Eventually, convert to "datetime" objects if you prefer to work with them
allNewDates = datetime(alldates(:) , 'ConvertFrom','datenum') ;
、これまでにさまざまな方法を迅速にベンチマーク:
とのコードしたい場合はわずか数行に低減することができるすべてのベンチマーク(tic/toc
の代わりにtimeit
を使用)、私のコードもちょっと圧縮してください:
function t = bench_datevec_generation()
% nDaysToGenerate = [10:10:100 200:100:900] ;
nDaysToGenerate = [10:10:60] ;
t = zeros(numel(nDaysToGenerate),3) ;
for k=1:numel(nDaysToGenerate)
nDays = nDaysToGenerate(k) ;
f1 = @() genDateTime_loop(nDays);
f2 = @() genDateTime_vectorized(nDays);
f3 = @() genDatenum(nDays);
t(k,1) = timeit(f1) ;
t(k,2) = timeit(f2) ;
t(k,3) = timeit(f3) ;
fprintf('Measuring time for nDays=%d\n',nDays)
end
end
function newDates = genDateTime_loop(nDays)
sDates = (datetime([1991,11,01]) + caldays(0:nDays)).';
% Remove Weekends from Dates
sDates = sDates(weekday(sDates)>1 &weekday(sDates)<7);
% Outer Loop to go through LIST OF DATES
newDates=datetime([],[],[],[],[],[]); %Initialize dateTime Place holder
for theDate =1:size(sDates,1)
[y,m,d] = ymd(sDates(theDate)); % Get y,m,d of each date in list
% START and END Time to create date time sequence each day listed in Date
% t1 and t2 are synced to each day in the date vector
t1 = datetime(y,m,d,08,30,00); t2 = datetime(y,m,d,15,00,00);
temp=t1 :minutes(1) :t2;
newDates=[newDates temp];
end
newDates = newDates.' ;
end
function newDates = genDateTime_vectorized(nDays)
sDates = (datetime([1991,11,01]) + caldays(0:nDays))';
% Remove Weekends from Dates
sDates = sDates(weekday(sDates)>1 &weekday(sDates)<7);
[Y,M,D] = ymd(sDates);
% Get y,m,d of first (or any) date in list to build the the h,m,s time range
[y,m,d] = ymd(sDates(1));
t1 = datetime(y,m,d,08,30,00); t2 = datetime(y,m,d,15,00,00);
temp = (t1:minutes(1):t2)';
[h,m,s]=hms(temp);
newDates = datetime([repelem([Y M D], length(temp), 1) repmat([h m s], [length(sDates) 1])]);
% repmat() to REPLICATE the TIME MATRIX, length(sDates) times along the rows
% repelem() to REPEAT EACH ELEMENT OF the DATE MATRIX, length(temp) times along the rows
end
function newDates = genDatenum(nDays)
% Initial parameters
StartDate = datenum(1991,11,01) ; % first day
% now create an array containing an integer multiple of 7 (days)
daysarray = reshape((0-weekday(StartDate)+1):(nDays+7-weekday(StartDate+nDays)),7,[]) ;
dowToRemove = [1 7] ;
daysarray(dowToRemove,:) = [] ;
daysarray(daysarray<0 | daysarray>nDays) = [] ;
daysarray = daysarray + StartDate ;
% Create the vector of minutes for any given day
step = 1/24/60 ; % portion of a day that represent a minute
start = datenum(0,0,0,8,30,0) ; % start time for each day
stop = datenum(0,0,0,15,00,00) ;% end time for each day
dailyvec = (start:step:stop).' ;
% Use bsxfun to create the complete arrays
alldates = bsxfun(@plus,daysarray,dailyvec) ;
% Eventually, convert to "datetime" objects if you prefer to work with them
newDates = datetime(alldates(:) , 'ConvertFrom','datenum') ;
end