6

私はPEP3118の厄介な実装に頭を悩ませようとしています。バッファアクセスはnumpyでどの程度正確に機能しますか。

>>> p = numpy.getbuffer(numpy.arange(10))
>>> p
<read-write buffer for 0x1003e5b10, size -1, offset 0 at 0x1016ab4b0>
>>> numpy.frombuffer(p)
array([  0.00000000e+000,   4.94065646e-324,   9.88131292e-324,
     1.48219694e-323,   1.97626258e-323,   2.47032823e-323,
     2.96439388e-323,   3.45845952e-323,   3.95252517e-323,
     4.44659081e-323])

だから私は予期しないリターンを得ています。0から9までの10個の要素を持つ配列が表示されると思います。ただし、配列にアクセスして読み取り/書き込みを行うことはできます。

>>> j = numpy.frombuffer(p)
>>> j
array([  0.00000000e+000,   4.94065646e-324,   9.88131292e-324,
     1.48219694e-323,   1.97626258e-323,   2.47032823e-323,
     2.96439388e-323,   3.45845952e-323,   3.95252517e-323,
     4.44659081e-323])
>>> j += 1
>>> j
array([ 1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.])

したがって、バッファはすべてゼロに初期化されているように見えます。これを書き込むことができます。私が期待している機能は、getbufferを使用してバッファーに直接配列(arangeまたはasarrayを使用)を構築できることです。それは不可能ですか?

4

2 に答える 2

16

簡単なdtype問題があります。で作成するバッファ

np.getbuffer(np.arange(10))

デフォルトでを使用するdtype=intため、があります。np.arangedtype=int

次に、バッファを読み込もうとすると

np.frombuffer(p)

dtype=float実際には、デフォルトの。を使用していますnp.frombuffer。代わりに、

np.frombuffer(p, dtype=int)

etvoilà、あなたは

array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
于 2012-09-17T15:38:19.737 に答える
9

ピエールによる優れた既存の回答にいくつかのコメントを追加さ​​せてください。

getbufferスライスする必要がある場合にのみ必要です:属性ndarrayを介して配列全体に関連付けられたPythonバッファオブジェクトを取得できますdata

>>> import numpy as np
>>> a = np.arange(10)
>>> a.data == np.getbuffer(a)
True

それどころか、実際のバッファオブジェクトを関数に渡す必要はありません。インターフェイスfrombufferを公開するすべてのオブジェクトは適切です。buffer

>>> np.frombuffer(a, a.dtype)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> np.frombuffer(a)
array([  0.00000000e+000,   4.94065646e-324,   9.88131292e-324,
         1.48219694e-323,   1.97626258e-323,   2.47032823e-323,
         2.96439388e-323,   3.45845952e-323,   3.95252517e-323,
         4.44659081e-323])
>>> import array
>>> c = array.array('i', range(10))
>>> np.frombuffer(c, np.int32)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=int32)
>>> np.frombuffer(c)
array([  2.12199579e-314,   6.36598737e-314,   1.06099790e-313,
         1.48539705e-313,   1.90979621e-313])

バッファオブジェクトをデコードするときdtypeは、上記の例が示すように正しいことを知っている必要があります。より正確に言うと、バッファオブジェクトには:がありませんdtype。これらは単なるバイナリデータのストリームです。代わりにndarray、オブジェクトにはdtype、基になるバイナリデータがどのように解釈されるかを指示するがあります。

あなたの質問に答えるために:すべてのnumpyndarrayはバッファインターフェースを公開します。data記述子またはgetbuffer関数を介して、バッファーまたはそのスライスにアクセスできます。ndarray関数を使用して、バッファインターフェイスを公開するオブジェクトからを作成できますfrombuffer。(ではなくndarrays)バッファには情報がないため、の引数をdtype使用して、バッファをどのように解釈する必要があるかを常に明示的に指定する必要があります。dtypefrombuffer

于 2012-09-17T23:11:39.173 に答える