【问题标题】:How do I read a delimited file with strings/numbers with Octave?如何使用 Octave 读取带有字符串/数字的分隔文件?
【发布时间】:2011-03-14 16:24:50
【问题描述】:

我正在尝试使用 Octave 读取包含数字和字符串的文本文件。文件格式是这样的:

A B C
10 100
b 20 200
c 30 300
d 40 400
e 50 500

但分隔符可以是空格、制表符、逗号或分号。如果分隔符是空格/制表符,则 textread 函数可以正常工作:

[A,B,C] = textread ('test.dat','%s %d %d','headerlines',1)

但是,如果分隔符是逗号/分号,它就不起作用。我尝试使用 dklmread:

dlmread ('test.dat',';',1,0)

但它不起作用,因为第一列是一个字符串。 基本上,使用 textread 我无法指定分隔符,使用 dlmread 我无法指定第一列的格式。至少在 Octave 中这些函数的版本不是这样。以前有人遇到过这个问题吗?

【问题讨论】:

    标签: io octave


    【解决方案1】:

    textread 允许您指定分隔符——它遵循strread 的属性参数。以下代码对我有用:

    [A,B,C] = textread( 'test.dat', '%s %d %d' ,'delimiter' , ',' ,1 )
    

    【讨论】:

      【解决方案2】:

      我目前在 Octave 中找不到简单的方法来执行此操作。您可以使用fopen() 循环文件并手动提取数据。我写了一个函数可以对任意数据执行此操作:

      function varargout = coltextread(fname, delim)
      
          % Initialize the variable output argument
          varargout = cell(nargout, 1);
      
          % Initialize elements of the cell array to nested cell arrays
          % This syntax is due to {:} producing a comma-separated 
          [varargout{:}] = deal(cell());
      
          fid = fopen(fname, 'r');
      
          while true
              % Get the current line
              ln = fgetl(fid);
      
              % Stop if EOF
              if ln == -1
                  break;
              endif
      
              % Split the line string into components and parse numbers
              elems = strsplit(ln, delim);
              nums = str2double(elems);
      
              nans = isnan(nums);
      
              % Special case of all strings (header line)
              if all(nans)
                  continue;
              endif
      
              % Find the indices of the NaNs 
              % (i.e. the indices of the strings in the original data)
              idxnans = find(nans);
      
              % Assign each corresponding element in the current line
              % into the corresponding cell array of varargout
              for i = 1:nargout
                  % Detect if the current index is a string or a num
                  if any(ismember(idxnans, i))
                      varargout{i}{end+1} = elems{i};
                  else
                      varargout{i}{end+1} = nums(i);
                  endif
              endfor
          endwhile
      
      endfunction
      

      它接受两个参数:文件名和分隔符。该函数由指定的返回变量的数量控制,因此,例如,[A B C] = coltextread('data.txt', ';'); 将尝试从文件中的每一行解析三个不同的数据元素,而A = coltextread('data.txt', ';'); 将只解析第一个元素。如果没有给出返回变量,那么函数将不会返回任何东西。

      该函数会忽略包含所有字符串的行(例如“A B C”标题)。如果您想要所有内容,只需删除 if all(nans)... 部分即可。

      默认情况下,“列”作为元胞数组返回,尽管这些数组中的数字实际上是转换后的数字,而不是字符串。如果您知道元胞数组仅包含数字,那么您可以轻松地将其转换为列向量:cell2mat(A)'

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-05-06
        • 2016-03-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-07-24
        相关资源
        最近更新 更多