2017-10-09 3 views
3

これは愚かな質問かもしれませんが、私はそれに適切な答えを見つけることができません。私は、(2000, 2000, 2000)の0の配列のバイナリ表現をディスク(バイナリ形式)に格納したい(理由は問いません)。バイナリファイルにゼロ(大量)を書き込んでください

with open('myfile', 'wb') as f: 
    f.write('\0' * 4 * 2000 * 2000 * 2000) # 4 bytes = float32 

しかし、これはまったく必要ではない非常に大きな文字列を作成することを意味します。文字列などの高価なメモリとして(numpyの配列を作成し、それをディスクにフラッシュする時要素と店舗1バイトを超える

  • 反復(非常に遅い)

  • :私は2つの他のオプションを知っています上記の例で作成)

私はwが、Cの速度ではなく、Pythonのループ速度でディスクcharntimesにコピーするwrite(char, ntimes)のようなものを(それはCと他の言語に存在するような)を見つけるためにホッピングされましたメモリ上にこのような大きな配列を作成する必要はありません。

+4

100k程度の妥当なサイズの文字列を作成してループで複数回書き出すのはなぜですか? –

+0

それはオプションですが、私は事前に配列の形を知っていません(2000^3が例です)。そして、妥当なサイズ*を計算し、Pythonの速度でループすることは依然として遅くなります。それは悪い解決策ではありません(そしてたぶん唯一のものです)が、私は、誰かがライブラリ/メソッド/私がループすることなくそれを行うことができない何かを思いつくことを望んでいた(例えば、Cython拡張) 。 –

+1

配列が密集している(パックされている)場合、シェイプは重要ではありません。合計バイト数だけです。このように見てください:1つの巨大な文字列を1回書くという例とは区別できないはずです。 –

答えて

1

私は、あなたが「Pythonのループ速度」について、このような大騒ぎを作っている理由がわからないけど、

for i in range(2000 * 2000): 
    f.write('\0' * 4 * 2000) # 4 bytes = float32 

の方法で書くことは8000 0バイトを書くためにOSを教えてくれます。 writeが返された後、次のループ実行で再び呼び出されます。

ループはC言語よりも少し遅く実行されるかもしれませんが、確かに違いはありません。

スパースファイルを作成しても問題ない場合は、希望するファイルサイズの位置までシークしてファイルを切り捨てることもできます。

+0

私はPythonループが嫌いではありません、私は他の選択肢を見てほしいと思っています、そしてうまくいけば、これより低いレベルのAPIです。どうやら、標準の 'write(byte、length)'はPythonでは利用できません。これは次善のものです。その配列の反復的な作成を避けるために、 'data = '\ 0' * 4 * 2000'ループから抜け出しますが、これもまた二次的です。 –

+0

@ImanolLuengo 'f.write(s)'はまさに標準の 'write(bytes、length)'です。長さは文字列にエンコードされています。文字列の一部を書きたい文字列がある場合は、スライスの代わりに 'buffer()'オブジェクト、 'write(buffer(longstring、10000、12))'を使うことができます。 – glglgl

-2

データ量は約30Gバイトです。 明らかに、ファイルに格納する前にRAMに格納することはできません。

たぶん最良の方法は、ディスク・クラスタのサイズのバッファを使用することです(4K、128K、512Kを?)

+0

RAMのサイズによって異なります。 – glglgl

1

これはnumpy's memmap:

shape = (2000, 2000, 2000) # or just (2000 * 2000 * 2000,) 
fp = np.memmap(filename, dtype='float32', mode='w+', shape=shape) 
fp[...] = 0 
を使ってPythonからファイルを埋めるために有効な回答になります
+0

これは@ glglglの回答より速いのですか? –

+1

@AnderBiguriおそらく、彼の答えは最初でした。 – glglgl

関連する問題