如何使用Octave读取带字符串/数字的分隔文件?

rs0*_*028 20 io octave

我正在尝试使用Octave读取包含数字和字符串的文本文件.文件格式如下:

ABC
a 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中没有这些功能的版本.以前有人遇到过这个问题吗?

小智 13

textread允许您指定分隔符 - 它尊重属性参数strread.以下代码对我有用:

[A,B,C] = textread( 'test.dat', '%s %d %d' ,'delimiter' , ',' ,1 )
Run Code Online (Sandbox Code Playgroud)


voi*_*hos 6

我目前在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
Run Code Online (Sandbox Code Playgroud)

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

该函数忽略具有全字符串的行(例如'ABC'标题).if all(nans)...如果你想要一切,只需删除该部分.

默认情况下,"列"作为返回单元阵列,虽然数字的数组实际上是转换数字,而不是字符串.如果你知道一个单元阵列只包含数字,那么你可以很容易地将其转换为一个列向量:cell2mat(A)'.