使用多个字符串调用sscanf

时间:2016-04-12 13:00:12

标签: string matlab date matrix scanf

我想将日期字符串转换为数字矩阵,我需要以非常高的速度进行操作。我的意见:

 dateStrings = [
     '2015 07 09 12 28 18.17641';
     '2015 07 09 12 28 19.17641';
     '2015 07 09 12 28 20.17641']

我现在想要使用sscanf将它们转换为数字。 (原因是它非常快)。如果dateStrings只包含1个字符串,这可以正常工作,但在这种情况下我有3个字符串。 (实际上是50 000 +)。

sscanf(dateStrings, '%d %d %d %d %d %f')

所需的输出是一个矩阵,如下所示:

 2015            7            9           12           28       18.176
 2015            7            9           12           28       19.176
 2015            7            9           12           28       20.176

有没有办法在使用多个字符串调用sscanf时,还是必须进行循环?

欢迎任何有关如何解决问题的建议,只要它快速!

编辑:Suever的解决方案给了我很大的速度!但是,上述输入并非如此。实际输入如下所示。既然你提到使用单元格实际上更快,你会怎么用这个输入呢?目前我使用cell2mat转换输入,然后用空格替换某些索引,最终得到像'2015 07 09 12 28 18.17641'这样的字符串。

Input is 4x1 cell:

    '2015-11-18T23:31:49.37486 +01:00'
    '2015-11-18T23:31:49.37583 +01:00'
    '2015-11-18T23:31:49.37658 +01:00'
    '2015-11-18T23:31:49.37735 +01:00'

1 个答案:

答案 0 :(得分:3)

2D角色阵列特别难以操纵。如果您首先使用cellstr将其转换为单元格,则可以更轻松地使用它。

C = cellstr(dateStrings);
output = sscanf(sprintf('%s ', C{:}), '%f');
output = reshape(output, [], numel(C)).';     %'

%//  2015            7            9           12           28       18.176
%//  2015            7            9           12           28       19.176
%//  2015            7            9           12           28       20.176

或者您可以使用cellfun

output = cellfun(@(x)sscanf(x, '%f'), C, 'uni', 0);
output = cat(2, output{:}).';

您还可以使用str2numstrjoin的组合。

output = reshape(str2num(strjoin(C)), [], numel(C)).';

老实说,循环查看初始数据可能是最快的选择。

output = NaN(size(dateStrings,1), 6);
for k = 1:size(dateStrings, 1);
    output(k,:) = sscanf(dateStrings(k,:), '%f');
end

我使用具有不同行数的输入对这些方法进行基准测试,并得到以下结果。第一和第三看起来是最高效的。

enter image description here

更新

由于您的初始问题根本不是您数据的准确表示,因此您现在需要将格式说明符更改为sscanf。您也可以直接传递输入单元格数组C,而不是使用cellstr

sscanf(x, '%d-%d-%dT%d:%d:%f +%*d:%*d')

所以我们可以将其应用于上面的一些答案:

%// Option #1
fmt = '%d-%d-%dT%d:%d:%f +%*d:%*d';
output = reshape(sscanf(sprintf('%s ', C{:}), fmt), [], numel(C)).';   %'

%// Option #2
output = cellfun(@(x)sscanf(x, fmt), C, 'uni', 0);
output = cat(2, output{:}).';   %'

%// Option #4
output = NaN(numel(C), 6);
for k = 1:numel(C)
    output(k,:) = sscanf(C{k}, fmt);
end