有没有人知道将日期字符串(2010-12-12 12:21:12.123)转换为数字的更快方法?
答案 0 :(得分: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是我的Windows机器上的内部函数(C:\ Program Files \ Matlab \ R2011a \ toolbox \ matlab \ timefun \ private \ dtstr2dtnummx.mexw32)。
要访问此内部函数,只需使用addpath
函数将其文件夹添加到Matlab路径,或将dtstr2dtnummx.mexw32文件复制到Matlab路径上已有的另一个文件夹。
请注意dtstr2dtnummx和datenum之间的字符串格式不同,所以要小心!
对于有兴趣的人,上面的文件夹包含其他有趣的日期转换功能,所以请探索并享受!
Note 5/5/2011:我现在发布了一篇文章,在http://undocumentedmatlab.com/blog/datenum-performance/
上扩展了这个答案答案 1 :(得分:2)
通常你需要采用系统方法。当我从数据库中提取数千个日期时,我遇到了一个非常类似的问题。事实证明,许多现代数据库(Postgres,Sql server和Oracle是我尝试过的)都可以进行从日期表示到Matlab日期表示的转换,比matlab端的文本日期更快几个数量级。 。如果此数据来自数据库,请考虑数据库端转换!!
答案 2 :(得分: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减少每次调用函数时计算日期格式的开销。
答案 3 :(得分:0)
我意识到这个问题已经过时了。但是,我设法创建的函数比datenum快大约30-40倍。注意:根据使用情况,存在一些小缺陷。如果有人想让我知道,请告诉我。
在1,792,379行上运行:
只需使用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