15

私は実質的に Matlab の知識がなく、いくつかの解析ルーチンを Python に変換する必要があります。それらは大きなファイル用で、それ自体が「ブロック」に分割されており、ファイルの上部にあるチェックサムで最初から問題が発生しています。

ここMatlabで何が起こっているのでしょうか?

status = fseek(fid, 0, 'cof');
fposition = ftell(fid);
disp(' ');
disp(['** Block ',num2str(iBlock),' File Position = ',int2str(fposition)]);

% ----------------- Block Start ------------------ %
[A, count] = fread(fid, 3, 'uint32');
if(count == 3)
    magic_l = A(1);
    magic_h = A(2);
    block_length = A(3);
else
    if(fposition == file_length)
        disp(['** End of file OK']);
    else
        disp(['** Cannot read block start magic !  Note File Length = ',num2str(file_length)]);
    end
    ok = 0;
    break;
end

fid は現在見ているファイルです iBlock はファイル内のどの「ブロック」にいるかのカウンターです

magic_l と magic_h は、後でチェックサムを処理するためのものです。そのためのコードは次のとおりです (上記のコードから直接続きます)。

disp(sprintf('  Magic_L = %08X, Magic_H = %08X, Length = %i', magic_l, magic_h, block_length));
correct_magic_l = hex2dec('4D445254');
correct_magic_h = hex2dec('43494741');

if(magic_l ~= correct_magic_l | magic_h ~= correct_magic_h)
    disp(['** Bad block start magic !']);
    ok = 0;
    return;
end

remaining_length = block_length - 3*4 - 3*4;   % We read Block Header, and we expect a footer
disp(sprintf('  Remaining Block bytes = %i', remaining_length));
  • %08Xともので何が起こっているのhex2decですか?
  • また、なぜ3*4代わりに指定するの12ですか?

実際には、ファイルの最初の 3 文字をプルするだけな[A, count] = fread(fid, 3, 'uint32');ので、Python でレプリケートする方法を知りたいです。io.readline()ここでポイントを逃した場合はお詫び申し上げます。ファイルを使用すると、本来あるべきではないものが返されるように見えるだけで、非常に長くなる可能性がある場合に、 が 1 バイトに収まるio.readline(3)方法がわかりません。block_length

このランブルを読んでくれてありがとう。私が知りたいことを理解していただければ幸いです!(どんな洞察も大歓迎です。)

4

4 に答える 4

20

1 次元配列を読み取るための Python コード

Matlab を Python に置き換えるとき、バイナリ データを に読み込もうとしたnumpy.arrayのでnumpy.fromfile、データを 1 次元配列に読み込んでいました。

import numpy as np

with open(inputfilename, 'rb') as fid:
    data_array = np.fromfile(fid, np.int16)

numpy.fromfile他の Python ソリューションと比較した場合の利点には、次のようなものがあります。

  • 読み取るアイテムの数を手動で決定する必要はありません。count=引数を使用して指定できますが、デフォルト-1では、ファイル全体を読み取ることを示します。
  • 開いているファイル オブジェクト (上記で で行ったようにfid) を指定するか、ファイル名を指定できます。私はオープン ファイル オブジェクトを使用することを好みますが、ファイル名を使用する場合は、上記の 2 行を次のように置き換えることができます。

    data_array = numpy.fromfile(inputfilename, numpy.int16)
    

2 次元配列の Matlab コード

Matlabfreadには、データを[m, n]列ベクトルに読み込むだけでなく、フォームの行列に読み込む機能があります。たとえば、データを 2 行の行列に読み込むには、次を使用します。

fid = fopen(inputfilename, 'r');
data_array = fread(fid, [2, inf], 'int16');
fclose(fid);

2 次元配列の同等の Python コード

このシナリオは、Numpy のshapeとを使用して Python で処理できtransposeます。

import numpy as np

with open(inputfilename, 'rb') as fid:
    data_array = np.fromfile(fid, np.int16).reshape((-1, 2)).T
  • は、他の次元に基づいてその次元の配列の長さを推測するように指示します。これは、Matlab の無限表現に相当し-1ます。numpy.reshapeinf
  • .T配列を転置して、最初の次元 (軸) の長さが 2 の 2 次元配列になるようにします。
于 2013-02-06T02:36:52.017 に答える
8

ドキュメントfreadから、バイナリデータを読み取る関数です。2 番目の引数は出力ベクトルのサイズを指定し、3 番目の引数は読み取った項目のサイズ/タイプを指定します。

これを Python で再作成するには、次のarrayモジュールを使用できます。

f = open(...)
import array
a = array.array("L")  # L is the typecode for uint32
a.fromfile(f, 3)

これにより、ファイルから 3 つの uint32 値が読み取られますf。これらはa後で使用できます。のドキュメントからfromfile:

ファイル オブジェクト f から n 個の項目を (マシンの値として) 読み取り、それらを配列の末尾に追加します。使用可能な項目が n 個未満の場合、EOFError が発生しますが、使用可能な項目は引き続き配列に挿入されます。f は実際の組み込みファイル オブジェクトでなければなりません。read() メソッドを使用した他の何かは機能しません。

配列はシーケンス プロトコルを実装するため、リストと同じ操作をサポートしますが、.tolist()メソッドを使用して配列から通常のリストを作成することもできます。

于 2010-01-27T10:44:25.530 に答える
2

本当だけど複製の仕方が知りたい[A, count] = fread(fid, 3, 'uint32');

Matlab では、fread()のシグネチャの 1 つが ですfread(fileID, sizeA, precision)。これは、ファイルの最初のsizeA要素 (バイトではない) を読み込みます。それぞれのサイズはprecision. この場合、 を読み込んでいるuint32ので、各要素のサイズは 32 ビット、つまり 4 バイトです。

そのため、代わりにio.readline(12)、ファイルから最初の 3 つの 4 バイト要素を取得してみてください。

于 2010-01-27T10:34:20.290 に答える
0

最初の部分は Torsten's answer でカバーされています...とにかく、このデータを必要とするarrayか、何かをする必要があります。numarray

%08X と hex2dec については、%08X はこれらの unit32 番号 (8 桁の 16 進数、Python とまったく同じ) の印刷形式であり、hex2dec('4D445254') は 0x4D445254 の matlab です。

最後に、matlab の ~= はビットごとの比較です。Python では == を使用します。

于 2010-01-27T11:37:33.673 に答える