2014-01-06 2 views
6

私のデータ(通常は30Gb〜60Gb)が大きすぎてコンピュータのメモリに収まらないため、memmapfileを使用することに決めました。MATLABのメモリマップファイル?

私のデータファイルは、2つのセンサーの出力に対応する2つのデータ列で構成されています。これらのデータファイルは.binと.txtの両方の形式です。

m=memmapfile('G:\E-Stress Research\Data\2013-12-18\LD101_3\EPS/LD101_3.bin','format','int32') 
m.data(1) 

『」私は「M」変数にメモリマップに自分のデータを上記のコードを使用するが、私はどのようなデータ形式(INT8' 、『INT16』、『INT32』、』 Int64型を使用する見当がつかない'uint16'、 'uint32'、 'uint64'、 'single'、 'double')を使用して、 実際には、MATLABがサポートしているすべてのデータ形式を試しましたが、m.data(インデックス番号)を使用した場合、期待通りの数のペア(データの2列)は得られません。私が使用したフォーマットによって異なります。

誰かがmemmapfileの経験がある場合は、私を助けてください。人々は私のデータが構成されている方法を理解することができるように

Hereは私のデータファイルの一部に小さいバージョンです:

歓声 ジェームズ

+0

普通のバイナリファイルがあると仮定すると、構造体はありません。すべてのデータは 'X(:)'と同様に行列にベクトル化された行に書き込まれます。バイナリファイルの書き方についての情報はありますか?そうでない場合は、小さなexample .txtファイルと.binファイルを作成してアップロードしてください。 – Daniel

+0

'' Format''オプションを使うと、 "array shape"を指定できるようです。 –

+0

@DanielRバイナリファイルの書き方はわかりませんが、比較的小さなファイルをいくつか作成してアップロードしました。 https://www.dropbox.com/sh/rzut4zbrert9fm0/q9SiZYmrdG –

答えて

5

memmapfileは、あなたの持つ問題を抱えている理由です、バイナリファイルを読み込むために設計されていますテキストファイル。そこにあるデータは文字なので、それらを文字として読んでから、数値に解析する必要があります。それについてもっと下に。

バイナリファイルには、バイナリ形式で記述された浮動小数点値のストリーム以上のものが含まれているようです。私は識別子(文字列)とファイル内の他のものも参照しています。読んでいただける唯一の希望は、バイナリファイルを作成したデバイスの製造元に問い合わせて、そのようなファイルの読み方を尋ねることです。おそらく、SDK、または少なくともフォーマットの説明があるでしょう。テキストファイルの浮動小数点数が切り捨てられる場合があります。つまり、浮動小数点数のバイナリ表現を直接読み取る場合に比べて精度が低下しているためです。

あなたのファイルをmemmapfileで読み取るにはどうすればよいですか? This postにはいくつかのヒントがあります。

だから、最初の我々は(回避策として、私たちは、同じサイズのデータ​​型にファイルの内容を読み込むので、何'char'オプションはありません注意してください)'uint8'としてあなたのファイルを開きます。

m = memmapfile('RTL5_57.txt','Format','uint8'); % uint8 is default, you could leave that off 

私たちは、レンダリングすることができますデータはcharにそれをキャストすることによって文字などのuint8として読み込ま:

c = char(m.Data(1:19)).' % read the first three lines. NB: transpose just for getting nice output, don't use it in your code 
c = 
    0.398516 0.063440 
    0.399611 0.063284 
    0.398985 0.061253 

あなたのファイルの各行が同じ長さ(2 * 8番号の文字、[1]タブと改行= 19文字2つの文字を持っていたよう)、私たちはN行を読むことができますファイルにはN*19の値を読み込みます。したがって、m.Data(1:19)は、第1行、m.Data(20:38)、第2行、第2行目と第3行目のm.Data(20:57)を取得します。一度に読んでください。

その後、我々は浮動小数点数に読み込んだデータを解析する必要があります:

f = sscanf(c,'%f') 
f = 
    0.3985 
    0.0634 
    0.3996 
    0.0633 
    0.3990 
    0.0613 

すべてのことは、今残っては

d = reshape(f,2,[]).' 
d = 
    0.3985 0.0634 
    0.3996 0.0633 
    0.3990 0.0613 

より簡単に2列形式にそれらを再構築することです方法を使用するよりmemmapfile: あなたの問題を解決するためにmemmapfileを使用する必要はありません、そして、それは事態をより複雑にすると思います。あなたは、単にfread続いfopenを使用することができます。

fid = fopen('RTL5_57.txt'); 
c = fread(fid,Nlines*19,'*char'); 
% now sscanf and reshape as above 
% NB: one can read the values the text file directly with f = fscanf(fid,'%f',Nlines*19). 
% However, in testing, I have found calling fread followed by sscanf to be faster 
% which will make a significant difference when reading such large files. 

あなたは、一度に値のNlinesペアを読んでそれらを処理し、単純に次のNlinesを読むために再びfreadを呼び出すことができ、これを使用します。 freadはファイル内にどこにあるかを覚えています(fscanf)ので、単に同じ呼び出しを使用して次の行を取得してください。そのため、ファイル全体を処理するためのループを書くのが簡単で、ファイルの最後にある場合はfeof(fid)でテストします。

さらに簡単な方法を提案しますheretextscanを使用してください。再びしかしsscanf続いfreadは最速となること

Nlines = 10000; 

% describe the format of the data 
% for more information, see the textscan reference page 
format = '%f\t%f'; 

fid = fopen('RTL5_57.txt'); 

while ~feof(fid) 
    C = textscan(fid, format, Nlines, 'CollectOutput', true); 
    d = C{1}; % immediately clear C at this point if you need the memory! 
    % process d 
end 

fclose(fid); 

注:少し自分のコード例を適応するには。ただし、freadメソッドは、テキストファイルに1行が書式と完全に一致しないとすぐに終了することに注意してください。一方、空白の変更を許さず、従ってより頑強である。

+0

本当に包括的かつ有用だった答えをありがとう。 –

関連する問題