我有一个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。
如果有人可以提供帮助,请提前多多谢谢!
答案 0 :(得分: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
的单元格数组:
加成: 如果您希望您的时间也是数字值(而不是字符串),请使用以下代码扩展名:
%% // 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)