8

ハードディスク上の大きな Fortran レコード (12G) を numpy 配列にマップしたいと考えています。(メモリを節約するためにロードする代わりにマッピングします。)

Fortran レコードに格納されたデータは、レコード マーカーで分割されているため、連続していません。レコード構造は「マーカー、データ、マーカー、データ、…、データ、マーカー」です。データ領域とマーカーの長さは既知です。

マーカー間のデータの長さは 4 バイトの倍数ではありません。それ以外の場合は、各データ領域を配列にマップできます。

最初のマーカーは memmap でオフセットを設定することでスキップできますが、他のマーカーをスキップしてデータを配列にマップすることは可能ですか?

あいまいな表現の可能性があることをお詫びし、解決策または提案に感謝します。


5月15日編集

これらは、フォーマットされていない Fortran ファイルです。レコードに格納されるデータは、(1024^3)*3 float32 配列 (12Gb) です。

2 ギガバイトを超える可変長レコードのレコード レイアウトを以下に示します。

データ構造

(詳しくはこちら→【レコードの種類】→【可変長レコード】の項をご覧ください。)

私の場合、最後のサブレコードを除いて、各サブレコードの長さは 2147483639 バイトで、8 バイトで区切られています (上の図でわかるように、前のサブレコードの終了マーカーと次のサブレコードの開始マーカー、8 バイトで合計 ) 。

2147483639 mod 4 =3 のように、最初のサブレコードが特定の浮動小数点数の最初の 3 バイトで終わり、2 番目のサブレコードが残りの 1 バイトで始まることがわかります。

4

1 に答える 1

3

ここに示した例が 機能したため、別の回答を投稿しnumpy.memmapました。

offset = 0
data1 = np.memmap('tmp', dtype='i', mode='r+', order='F',
                  offset=0, shape=(size1))
offset += size1*byte_size
data2 = np.memmap('tmp', dtype='i', mode='r+', order='F',
                  offset=offset, shape=(size2))
offset += size1*byte_size
data3 = np.memmap('tmp', dtype='i', mode='r+', order='F',
                  offset=offset, shape=(size3))

for int32 byte_size=32/8、 forint16 byte_size=16/8など...

サイズが一定の場合、次のように 2D 配列にデータをロードできます。

shape = (total_length/size,size)
data = np.memmap('tmp', dtype='i', mode='r+', order='F', shape=shape)

memmap必要に応じてオブジェクトを変更できます。同じ要素を共有する配列を作成することさえ可能です。その場合、一方で行われた変更は他方で自動的に更新されます。

その他の参照:

于 2013-05-16T21:20:56.127 に答える