我有一个名为' datetime'的单元格数组。如下格式: 2009.01.01 00:00:02.169
这个' datetime'数组是1819833x1大小,这是大!!! 我想把它分成2个单元格阵列:' date'而且'时间' 日期=' 2009.01.01'和时间=' 00:00:02.169'。
所以我使用for循环如下:
for i=1:numel(datetime)
[date(i), time(i)] = strread(datetime{i},'%s%s','delimiter',' ');
end
正如您所看到的,它使用循环,并且在处理如此大的数据时速度非常慢。 我今天下午尝试了代码,差不多一个小时过去了,工作还没有完成....
那么有人可以给我一个建议吗? 谢谢!
答案 0 :(得分:2)
首先,我要预先分配date
和time
,不要选择哪种解决方案。接下来,我使用以下设置进行了一些实验
s = '2009.01.01 00:00:02.169';
S = repmat({s}, 100000, 1);
结果
使用strread
tic, for i=1:numel(S), [~, ~] = strread(S{i},'%s%s','delimiter',' '); end, toc
Elapsed time is 3.694143 seconds.
使用regexp
tic, for i=1:numel(S), [~] = regexp(S{i},'\s+', 'split'); end, toc
Elapsed time is 1.324754 seconds.
使用cellfun
tic, cellfun(@(x) regexp(x, '\s+', 'split'), S, 'UniformOutput', false); toc
Elapsed time is 2.072437 seconds.
正如您所看到的,大多数方法都很慢。幸运的是,MATLAB中的许多函数都可以直接使用单元格,请注意:
tic, Sresult = regexp(S, '\s+', 'split'); toc
Elapsed time is 0.253819 seconds.
您现在可以通过Sresult{i}{1}
或Sresult{i}{2}
或简单地
date = cellfun(@(x) x{1}, Sresult, 'UniformOutput', false);
time = cellfun(@(x) x{2}, Sresult, 'UniformOutput', false);
Elapsed time is 0.835277 seconds.
超快速方法
我能想到的最快的方法是要求格式始终相同,即每个字符串的长度相等。在你的情况下,我可以想象它是真的。然后你可以使用这样的东西
tic, Sa = cell2mat(S); Sdate = Sa(:,1:10); Stime = Sa(:, 12:end); toc
Elapsed time is 0.060586 seconds.
这里你得到另一个约20的速度因子!
答案 1 :(得分:0)
这是一种方法。不确定它会有多快:
datetime = {'2009.01.01 00:00:02.169'
'2009.01.02 00:01:05.169'}; %// example data. Cell array of strings
datetime_split = regexp(datetime, '\s+', 'split'); %// split according to spaces
%// Alternatively: datetime_split = cellfun(@strsplit, datetime, 'uniformoutput', 0);
datetime_split = [datetime_split{:}];
date = datetime_split(1:2:end);
time = datetime_split(2:2:end);
根据以上数据,这会产生
>> date
date =
'2009.01.01' '2009.01.02'
>> time
time =
'00:00:02.169' '00:01:05.169'
答案 2 :(得分:0)
所以,谢谢罗伯特......你的建议真有帮助! 首先,我做了预分配,循环+ strread()组合的时间减少到小于40秒我的' datetime'数组大小为1819833x1。
所以这是主要的改进,我们可以看到减少内存重新分配和内存数据复制可以加快这个过程....特别是当你对大量的样本数据执行时。