2017-11-01 7 views
0

私は弱い配列を読み書きするためにpickleライブラリを使用してきましたが、それらは非常に大きくなる傾向があります。より良い方法があるかどうかを調べるために、thisページ(図表のもの)のMarkの答えが見つかりました。基本的には、バイナリファイルとして保存することは、最速で読み書きが可能であるだけでなく、最小のメモリ量を占めるように見えます。だから私はhis github linkをクリックし、96行目で彼がndarraysを保存するために使うコードを見つけました。彼のコードは次のとおりです。誰かがこのコードで何が起きているのかをバイナリファイルとして保存することができますか?

class Binary(TimeArrStorage): 
    def save(self, arr, pth): 
     with open(pth, 'wb+') as fh: 
      fh.write(b'{0:s} {1:d} {2:d}\n'.format(arr.dtype, *arr.shape)) 
      fh.write(arr.data) 
      sync(fh) 

    def load(self, pth): 
     with open(pth, 'rb') as fh: 
      dtype, w, h = str(fh.readline()).split() 
      return frombuffer(fh.read(), dtype=dtype).reshape((int(w), int(h))) 

私の具体的な質問があり、fh.writeする最初の呼び出しに渡された文字列の意味は何ですか?前の "b"はバイナリを意味すると仮定しますが、{0:s} {1:d} {2:d}はどうでしょう。 2番目の質問は、このメソッドを任意のデータ型のndarrayに使用できるかどうかです。 3番目の質問は、同期メソッドを呼び出す必要があるということです(メソッドはgithubページの一番上に定義されています)。そして、最後の質問は、arrがndarrayであり、基本的にデータの開始位置のメモリ位置である場合、arr.dataが返すものを調べました。このコードは、それが書きたいオブジェクトの最後に到達したことをどのようにして知っていますか?

+0

'.format'のpython3で導入された文字列フォーマット方法です。 '%'などの古い方法では 'np.save/load'は同じサイズのファイルを生成するはずです。彼らは形状とdtypeの情報(80バイトのようなもの)を格納するために固定サイズのprelimnaryバッファを使います。 – hpaulj

答えて

0

私は(別の質問から)

In [509]: arr 
Out[509]: 
array([[-1.0856306 , 0.99734545], 
     [ 0.2829785 , -1.50629471], 
     [-0.57860025, 1.65143654]]) 

私はその属性で文字列の書式を設定できます:

In [510]: '%s %d %d'%(arr.dtype, *arr.shape) 
Out[510]: 'float64 3 2' 

あなたの例ではフォーマットがPY3でエラーになります(それはPY2でOKです) :

In [500]: '{0:s} {1:d} {2:d}'.format(arr.dtype, *arr.shape) 
... 
TypeError: non-empty format string passed to object.__format__ 

これはokです:

In [515]: '{0} {1} {2}'.format(arr.dtype, *arr.shape) 
Out[515]: 'float64 3 2' 

In [533]: '{0!s} {1:d} {2:d}'.format(arr.dtype, *arr.shape) 
Out[533]: 'float64 3 2' 

2次元配列の場合、arr.shapeは2要素タプルで、*arr.shapeはそれを展開します。 2d配列の場合、3つの引数があります。

これであなたはそれを言いますarr.dataは面白く見えます。私は彼らがデータバッファの内容全体を意味すると思うが、この特定の属性は内容ではなくアドレスである。

私がコメントで述べたように、np.saveは基本的に同じものですが、少し大きめの初期ブロックがあります。このコードがバグの場合は、試してみたnp.saveを使用することをお勧めします。

フルnp.saveコードを見るにはnp.lib.npyio.formatをご覧ください。これは、ヘッダを書き込み、その後でのDataBufferを書き込みます

array.tofile(fp) 

np.loadはそれができるならばnp.fromfileを使用しますが、frombufferを使用するようにフォールバックします。


PY2では、この作品:

>>> arr=np.ones((2,3)) 
>>> b'{0:s} {1:d} {2:d}'.format(arr.dtype, *arr.shape) 
'float64 2 3' 
関連する問題