Matlab 使用textscan读取数据块

Matlab 使用textscan读取数据块,matlab,file-io,textscan,Matlab,File Io,Textscan,如何提取每个月的“平均值”和“深度”数据 MEAN, S.D., NO. OF OBSERVATIONS January February ... Depth Mean S.D. #Obs Mean S.D. #Obs ... 0 32.92 0.43 9 32.95 0.32 21

如何提取每个月的“平均值”和“深度”数据

MEAN, S.D., NO. OF OBSERVATIONS


                      January                February       ...            
 Depth       Mean   S.D.  #Obs       Mean   S.D.  #Obs       ...
     0      32.92   0.43     9      32.95   0.32    21      
    10      32.92   0.43    14      33.06   0.37    48      
    20      32.88   0.46    10      33.06   0.37    50      
    30      32.90   0.51     9      33.12   0.35    48      
    50      33.05   0.54     6      33.20   0.42    41      
    75      33.70   1.11     7      33.53   0.67    37      
   100      34.77            1      34.47   0.42    10      
   150                                                                                           
   200

                         July                  August               
 Depth       Mean   S.D.  #Obs       Mean   S.D.  #Obs       
     0      32.76   0.45    18      32.75   0.80    73      
    10      32.76   0.40    23      32.65   0.92   130      
    20      32.98   0.53    24      32.84   0.84   121     
    30      32.99   0.50    24      32.93   0.59   120      
    50      33.21   0.48    16      33.05   0.47   109      
    75      33.70   0.77    10      33.41   0.73    80      
   100      34.72   0.54     3      34.83   0.62    20      
   150                              34.69            1                                                     
   200 
它在数据和开头的介绍行之间有不可定义的空格数


谢谢大家!

下面是一个如何从文件中读取行的示例:

fid = fopen('yourfile.txt');

tline = fgetl(fid);
while ischar(tline)
    disp(tline)
    tline = fgetl(fid);
end

fclose(fid);

在while循环中,您需要使用(或类似的东西)将每一行分解为由空格分隔的字符串标记。

Matlab的regexp功能强大,可以从结构较少的文本中提取数据。一般来说,非常值得熟悉正则表达式:

在本例中,您将定义捕获每个观察组的模式(平均SD Obs),例如:32.92 0.43 9

这里我看到了每组数据的模式:每组前面有6个空格(正则表达式=\s{6}),3个数据点被小于6个空格(\s+)分割。数据本身由两个浮点(\d+。\d+)和一个整数(\d+)组成:

所以,把这些放在一起,您的捕获模式看起来像这样(括号围绕着要捕获的数据模式):

我们可以通过在括号内添加“?”来为每个令牌(即组中要捕获的每个数据点)添加名称:

expr = '\s{6}(?<mean>\d+\.\d+)\s+(?<sd>\d+\.\d+)\s+(?<obs>\d+)';

变量“tokens”将包含一系列观察组,“data”是一个带有.mean.sd和.obs字段的结构(因为它们是“expr”中的标记名)。

如果您只想获得前两列,那么textscan()是一个不错的选择

fid = fopen('yourfile.txt');

tline = fgetl(fid);
while ischar(tline)
    oneCell = textscan(tline, '%n'); % read the whole line, put it into a cell
    allTheNums = oneCell{1}; % open up the cell to get at the columns

    if isempty(allTheNums) % no numbers, header line
        continue;
    end

    usefulNums = allTheNums(1:2) % get the first two columns
end

fclose(fid);
textscan
在有空格的地方自动分割输入的字符串,因此列之间未定义的字符串数不成问题。没有数字的字符串将给出一个数组,您可以将该数组测试为空,以避免越界或错误的数据

如果需要通过编程确定要获取哪些列,可以扫描单词“Depth”和“Mean”来查找索引。正则表达式在这里可能会有所帮助,但
textscan
也可以正常工作

strFile = urlread('file://mydata.txt');
[tokens data] = regexp(strFile, expr, 'tokens', 'names');
fid = fopen('yourfile.txt');

tline = fgetl(fid);
while ischar(tline)
    oneCell = textscan(tline, '%n'); % read the whole line, put it into a cell
    allTheNums = oneCell{1}; % open up the cell to get at the columns

    if isempty(allTheNums) % no numbers, header line
        continue;
    end

    usefulNums = allTheNums(1:2) % get the first two columns
end

fclose(fid);