将复杂的格式.txt文件读入Matlab

时间:2015-08-03 15:10:20

标签: matlab textscan

我有一个txt文件,我想读入Matlab。数据格式如下:

term2 2015-07-31-15_58_25_612 [0.9934343, 0.3423043, 0.2343433, 0.2342323]
term0 2015-07-31-15_58_25_620 [12]
term3 2015-07-31-15_58_25_625 [2.3333, 3.4444, 4.5555]
...

如何以下列方式阅读这些数据?

name = [term2 term0 term3] or namenum = [2 0 3]
time = [2015-07-31-15_58_25_612 2015-07-31-15_58_25_620 2015-07-31-15_58_25_625]
data = {[0.9934343, 0.3423043, 0.2343433, 0.2342323], [12], [2.3333, 3.4444, 4.5555]}

我尝试以这种方式使用textscan 'term%d %s [%f, %f...]',但对于最后一个数据部分,我无法指定长度,因为它们不同。那我该怎么读呢?我的Matlab版本是R2012b。

如果有人可以提供帮助,请提前多多谢谢!

2 个答案:

答案 0 :(得分:1)

在一次通过中可能有一种方法可以做到这一点,但对我来说,使用2遍方法更容易对这些问题进行排序。

  • 传递1:根据类型(字符串,整数等)读取所有具有常量格式的列,并在单独的列中读取非常量部分,该列将在第二次传递中处理。
  • 第2道:根据具体情况处理不规则柱。

对于您的样本数据,它看起来像这样:

%% // read file 
fid = fopen('Test.txt','r') ;
M = textscan( fid , 'term%d %s %*c %[^]] %*[^\n]'  ) ;
fclose(fid) ;

%% // dispatch data into variables
name = M{1,1} ;
time = M{1,2} ;
data = cellfun( @(s) textscan(s,'%f',Inf,'Delimiter',',') , M{1,3} ) ;

发生了什么:
第一个textscan指令读取完整文件。在格式说明符中:

  • term%d在文字表达式'term'之后阅读整数
  • %s读取代表日期的字符串
  • %*c忽略一个字符(忽略字符'[')。
  • %[^]]读取所有内容(作为字符串),直到找到字符']'
  • %*[^\n]忽略所有内容,直到下一个换行符('\n')。 (不捕获最后一个']'

之后,前两列很容易被分派到自己的变量中。结果单元数组M的第3列包含不同长度的字符串,包含不同数量的浮点数。我们将cellfun与另一个textscan结合使用来读取每个单元格中的数字并返回包含double的单元格数组:

textscan advanced

加成: 如果您希望您的时间也是数字值(而不是字符串),请使用以下代码扩展名:

%% // read file 
fid = fopen('Test.txt','r') ;
M = textscan( fid , 'term%d %f-%f-%f-%f_%f_%f_%f %*c %[^]] %*[^\n]'  ) ;
fclose(fid) ;

%% // dispatch data
name = M{1,1} ;
time_vec = cell2mat( M(1,2:7) ) ;
time_ms  = M{1,8} ./ (24*3600*1000) ;   %// take care of the millisecond separatly as they are not handled by "datenum"
time = datenum( time_vec ) + time_ms ;
data = cellfun( @(s) textscan(s,'%f',Inf,'Delimiter',',') , M{1,end} ) ;

这将为您提供一个数组time,其中包含一个Matlab时间序列号(通常比字符串更容易使用)。为了向您显示序列号仍然代表正确的时间:

>> datestr(time,'yyyy-mm-dd HH:MM:SS.FFF')
ans =
2015-07-31 15:58:25.612
2015-07-31 15:58:25.620
2015-07-31 15:58:25.625

答案 1 :(得分:0)

对于像这样的复杂字符串解析情况,最好使用regexp。在这种情况下,假设您拥有文件data.txt中的数据,以下代码应该可以满足您的需求:

txt = fileread('data.txt')
tokens = regexp(txt,'term(\d+)\s(\S*)\s\[(.*)\]','tokens','dotexceptnewline')

% Convert namenum to numeric type
namenum = cellfun(@(x)str2double(x{1}),tokens)

% Get time stamps from the second row of all the tokens
time = cellfun(@(x)x{2},tokens,'UniformOutput',false);

% Split the numbers in the third column 
data = cellfun(@(x)str2double(strsplit(x{3},',')),tokens,'UniformOutput',false)