使用textscan - 可变列长度将ASC文件读入MATLAB

时间:2015-07-22 21:25:58

标签: matlab file-io textscan

我正在尝试将以下数据读入MATLAB:

'0.000000 1  18EFFA59x  Rx D 8  AD  09  02  00  00  00  00  30'  
'0.004245 1  14EFF01Cx  Rx D 6  DB  00  FF  FF  00  71'  
'0.004640 1  CEF801Cx   Rx D 3  3F  00  3B'  
'0.005130 1  14EF131Cx  Rx D 6  DB  00  FF  FF  00  71'  
'0.005630 1  CEF801Cx   Rx D 3  3F  00  C3'  
'0.010015 1  18EFFA59x  Rx D 8  AD  07  01  00  00  00  00  30'  
'0.014145 1  CF004F0x   Rx D 8  F0  FF  7D  00  00  FF  FF  FF'  
'0.015060 1  18EFFA59x  Rx D 8  AD  07  02  00  00  00  00  30'  
'0.018235 1  18EF1CF0x  Rx D 8  F2  1E  05  FF  FF  00  71  FF'  
'0.018845 1  18EA5941x  Rx D 3  09  FF  00'  

我可以很容易地在每一行中读取字符串 - 但为了使后处理更有效率,我想通过其分隔符(即空格)分隔每一行。换句话说,最终结果应该是非单例单元格数组。我似乎无法找到一种非常有效的方法。效率很重要,因为这些文件长达数百万行,在MATLAB中使用字符串/单元格进行处理需要很长时间。

任何帮助将不胜感激。感谢。

1 个答案:

答案 0 :(得分:0)

你似乎有固定宽度的字段,所以我会这样处理它,让textscan通过关闭分隔符和空格并明确定义字段宽度和类型让你做大部分的预处理:

test = {...
    '0.000000 1  18EFFA59x  Rx D 8  AD  09  02  00  00  00  00  30'
    '0.004245 1  14EFF01Cx  Rx D 6  DB  00  FF  FF  00  71'
    '0.004640 1  CEF801Cx   Rx D 3  3F  00  3B'
    '0.005130 1  14EF131Cx  Rx D 6  DB  00  FF  FF  00  71'
    '0.005630 1  CEF801Cx   Rx D 3  3F  00  C3'
    '0.010015 1  18EFFA59x  Rx D 8  AD  07  01  00  00  00  00  30'
    '0.014145 1  CF004F0x   Rx D 8  F0  FF  7D  00  00  FF  FF  FF'
    '0.015060 1  18EFFA59x  Rx D 8  AD  07  02  00  00  00  00  30'
    '0.018235 1  18EF1CF0x  Rx D 8  F2  1E  05  FF  FF  00  71  FF'
    '0.018845 1  18EA5941x  Rx D 3  09  FF  00'};

test = strjoin(test', '\n');

C = textscan(test, '%8.6f %2u %11s %4s %2s %2u %33s', 'delimiter', '','whitespace','');

col1 = C{1};
col2 = C{2};
col3 = strtrim(C{3});
col3 = cellfun(@(x)hex2dec(x(1:end-1)), col3); % for instance.
col4 = strtrim(C{4});
col5 = strtrim(C{5});
col6 = C{6};
col7 = strtrim(C{7});

在现实世界中,您将文本字符串替换为文件ID。对于最后一个可变长度字段,只需读取整个内容,确保指定最大可能长度。 MATLAB将读取一个字段,直到它到达结尾或到达换行符(实际上,我将最后一个字段宽度1放大,只是为了确保)。然后将每个字段聚合到一个单元格中。我还冒昧地将第三个字段从十六进制转换为十进制,以显示如何进一步对数字进行后处理。

另外请注意,如果您确实拥有巨大的文件且需要最高速度,则可以通过指定strtrim n 来跳过字符字段上的%*ns步骤对于任何已知的间隙,例如第3列和第4列之间的2个字符间隙,是所需的字段宽度。星形表示忽略该字段。然而,我发现这种做事方式更具可读性和直观性,并且在其中一个字段(例如第4个字段)偶尔有3个字符条目时会留下一小部分错误。