2011-04-28 66 views
5

有誰知道將日期字符串(2010-12-12 12:21:12.123)轉換爲數字的更快方法嗎?比MATLAB中的datenum更快的功能

+0

通過數字,你是一個時間戳,如經常使用「自紀元秒」? – 2011-04-28 12:56:32

回答

18

通常講授內置Matlab函數並提取感興趣的內部功能。

在您的特定情況下,

dtstr2dtnummx({'2010-12-12 12:21:12.123'},'yyyy-MM-dd HH:mm:ss') 

大於3倍的速度(花費的時間的30%):

datenum({'2010-12-12 12:21:12.123'},'yyyy-mm-dd HH:MM:SS') 

其中dtstr2dtnummx是一個內部函數(C:\ Program Files文件\ Matlab \ R2011a \ toolbox \ matlab \ timefun \ private \ dtstr2dtnummx.mexw32在我的Windows機器上)。

要訪問此內部函數,只需使用addpath函數將其文件夾添加到Matlab路徑中,或者將dtstr2dtnummx.mexw32文件複製到您的Matlab路徑中已存在的另一個文件夾中。

請注意,dtstr2dtnummx和datenum之間的字符串格式不同,所以要小心!

對於那些有興趣的,上面的文件夾包含其他有趣的日期轉換功能,所以探索和享受!

2011/5/5注:我現在已經張貼擴展了http://undocumentedmatlab.com/blog/datenum-performance/

+0

不幸的是,您不能將私有Matlab目錄添加到路徑中,因此對於沒有將文件複製到當前目錄的用戶,此解決方案將無法工作。 – 2013-02-07 18:36:55

+0

爲了澄清,由於版權問題,用戶可能無法將包含'dtstr2dtnummx'的文件添加到其當前目錄。 – 2013-02-07 18:52:36

+0

@Ricardo - 我不認爲這裏有任何版權問題。我相信您在購買Matlab許可證時有權使用任何內部功能。 – 2013-02-07 22:25:17

2

通常你需要採取系統方法這個答案的文章。當我從數據庫中提取數千個日期時,我遇到了一個非常類似的問題。事實證明,許多現代數據庫(Postgres,SQL服務器&甲骨文是我嘗試的)都可以做從日期表示到Matlab日期表示的轉換,其數量比matlab方面的日期數字快幾個數量級。如果這些數據來自數據庫,請考慮DB端轉換!

2

想必如果你在意轉換日期的時間,你可以轉換很多其中。即使在最新版本的MATLAB的一邊JIT優化,你會得到更快的結果調用

datenum(cellarrayofdates, 'yyyy-mm-dd HH:MM:SS'); 

for i=1:length(cellarrayofdates); datenum(cellarrayofdates{i}, 'yyyy-mm-dd HH:MM:SS'); end 

如果你還沒有這樣做,從那裏開始,因爲它允許以MATLAB減少每次調用函數時計算日期格式的開銷。

0

我意識到這個問題是舊的。但是,我設法創建了比datenum快大約30-40倍的函數。注意:根據使用情況有一些小缺陷。如果有人想讓我知道它,請讓我知道。

在1792379行運行:

  • datenum - 11.463186秒
  • datenumjck - 0.300503秒

與textscan剛剛看了你的文件,並與日期一起解釋日期和時間,雙打和輸入格式到我的功能。

實施例:

假設數據被格式化爲下列:

Data,2016-03-03,16:15:50;686,0.000000,-0.009500 
Data,2016-03-03,16:15:50;696,0.000000,0.006500 
Data,2016-03-03,16:15:50;706,0.000000,0.004500 
Data,2016-03-03,16:15:50;716,0.000000,-0.006000 

讀數據:

fileID = fopen('myFile.csv','r'); 
formatSpec = '%*s %f %f %f %f %f %f %f %*[^\n]'; % Ignore first string, save 
               % date and time as doubles 
               % ignore all other data 
data = textscan(fileID,formatSpec,'delimiter',',\t/:;-.\\ '); 
fclose(fileID); 

指定日期格式並使用datenumjck():

dateFormat = 'yyyy-mm-dd,HH:MM:SS;FFF'; 
numDate = datenumjck(data,dateFormat); 

代碼:

function num = datenumjck(data, dateFormat) 

n = size(data{1}); 
dateFormat = textscan(dateFormat,'%s','delimiter',',/:;-.\\'); 
dateFormat = dateFormat{1}; 

k = find(strcmp('yyyy', dateFormat),1); 
if ~isempty(k) 
    y = data{k}; 
elseif ~isempty(find(strcmp('yy', dateFormat),1)) 
    y = data{find(strcmp('yy', dateFormat),1)}; 
else 
    y = zeros(n); 
end 

k = find(strcmp('mm', dateFormat),1); 
if ~isempty(k) 
    m = data{k}; 
elseif ~isempty(find(strcmp('mmm', dateFormat),1)) 
    month = cellfun(@strfind,... 
     repmat({'janfebmaraprmayjunjulaugsepoctnovdec'},... 
     size(data),lower(data(find(strcmp('mmm', dateFormat),1))))); 
    m = (month+2)/3; 
else 
    m = zeros(n); 
end 

k = find(strcmp('dd', dateFormat),1); 
if ~isempty(k) 
    d = data{k}; 
else 
    d = zeros(n); 
end 

k = find(strcmp('HH', dateFormat),1); 
if ~isempty(k) 
    H = data{k}; 
else 
    H = zeros(n); 
end 

k = find(strcmp('MM', dateFormat),1); 
if ~isempty(k) 
    M = data{k}; 
else 
    M = zeros(n); 
end 


k = find(strcmp('SS', dateFormat),1); 
if ~isempty(k) 
    S = data{k}; 
else 
    S = zeros(n); 
end 

k = find(strcmp('FFF', dateFormat),1); 
if ~isempty(k) 
    F = data{k}; 
else 
    F = zeros(n); 
end 

ms = [0,31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]; 

num = zeros(n); 
for k = 1:n 
    num(k) = y(k)*365 + ms(m(k)) + d(k) + floor(y(k)/4)... 
     - floor(y(k)/100) + floor(y(k)/400) + (mod(y(k),4)~=0)... 
     - (mod(y(k),100)~=0) + (mod(y(k),400)~=0)... 
     + (H(k)*3600 + M(k)*60 + S(k) + F(k)/1000)/86400 + 1; 
end