web-dev-qa-db-ja.com

Octaveで文字列/数値の区切られたファイルを読み取るにはどうすればよいですか?

Octaveを使用して、数字と文字列を含むテキストファイルを読み込もうとしています。ファイル形式は次のようなものです:

A B C
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のこれらの関数のバージョンでは、少なくともそうではありません。これまでに誰かがこの問題を抱えたことはありますか?

21
rs028

textread 区切り文字を指定できます- strread のプロパティ引数を受け入れます。次のコードは私のために働きました:

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

現在、オクターブでこれを行う簡単な方法を見つけることができませんでした。 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
_

これは、ファイル名と区切り文字の2つの引数を受け入れます。関数は指定された戻り変数の数によって制御されるため、たとえば、[A B C] = coltextread('data.txt', ';');はファイルの各行から3つの異なるデータ要素を解析しようとしますが、A = coltextread('data.txt', ';');は最初の要素のみを解析します。戻り変数が指定されていない場合、関数は何も返しません。

この関数は、すべての文字列(「A B C」ヘッダーなど)を含む行を無視します。すべてが必要な場合は、if all(nans)...セクションを削除してください。

デフォルトでは、「列」はセル配列として返されますが、数値withinは、実際には文字列ではなく変換された数値です。セル配列に数値のみが含まれていることがわかっている場合は、cell2mat(A)'を使用して簡単に列配列に変換できます。

6
voithos