使用textscan读取数据块

时间:2012-07-08 22:20:04

标签: 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      
    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 

数据之间有不可确定的空格数,并且在开头有一个引入行。

谢谢!

3 个答案:

答案 0 :(得分:0)

以下是如何从文件中读取行的示例:

fid = fopen('yourfile.txt');

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

fclose(fid);

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

答案 1 :(得分:0)

Matlab的regexp非常强大,可以从结构较少的文本中提取数据。通常值得熟悉正则表达式:http://www.mathworks.com/help/techdoc/ref/regexp.html

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

在这里,我看到每组数据的模式:每组前面有6个空格(正则表达式= \ s {6}),3个数据点除以少于6个空格(\ s +)。数据本身包含两个浮点数(\ d +。\ d +)和一个整数(\ d +):

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

expr = '\s{6}(\d+\.\d+)\s+(\d+\.\d+)\s+(\d+)';

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

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

然后,只需将您的文件读入一个字符串变量'strFile',然后使用此定义的模式提取数据:

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

变量'tokens'将包含一系列观察组,'data'是具有字段.mean .sd和.obs的结构(因为这些是'expr'中的标记名称)。

答案 2 :(得分:0)

如果您只想获得前两列,那么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会自动将您提供的字符串拆分到有空格的位置,因此列之间未定义的字符串数量不是问题。没有数字的字符串将给出一个可以测试为空的数组,以避免出界或数据错误。

如果您需要以编程方式确定要获取哪些列,则可以扫描“深度”和“均值”字样以查找缺陷。正则表达式在这里可能会有所帮助,但textscan也可以正常工作。