20

Numpy には、 aを長さ 8 のビット ベクトルにnp.unpackbitsアンパックするライブラリ関数uint8があります。より大きな数値型をアンパックする対応する高速な方法はありますか? たとえばuint16、またはuint32。私は、配列のインデックス付け、およびそれらのビット ベクトル表現のための数値間の頻繁な変換を含む質問に取り組んでおり、ボトルネックは pack および unpack 関数です。

4

4 に答える 4

19

viewとでこれを行うことができますunpackbits

入力:

unpackbits(arange(2, dtype=uint16).view(uint8))

出力:

[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0]

これは、a = arange(int(1e6), dtype=uint16)私のマシンでは約7ミリ秒とかなり高速です

%%timeit
unpackbits(a.view(uint8))

100 loops, best of 3: 7.03 ms per loop

エンディアンについては、http://docs.scipy.org/doc/numpy/user/basics.byteswapping.htmlを見て、必要に応じて提案を適用する必要があります。

于 2013-08-18T06:16:47.323 に答える
3

これに対する関数も見つかりませんでしたが、Python の組み込みの struct.unpack を使用すると、カスタム関数をシフトして長い uint を AND 処理するよりも高速にすることができます (uint64 を使用していることに注意してください)。

>>> import struct
>>> N = np.uint64(2 + 2**10 + 2**18 + 2**26)
>>> struct.unpack('>BBBBBBBB', N)
(2, 4, 4, 4, 0, 0, 0, 0)

アイデアは、それらを uint8 に変換し、unpackbits を使用して、結果を連結することです。または、アプリケーションによっては、構造化配列を使用する方が便利な場合があります。

0 と 1 の文字列を生成する組み込みの bin() 関数もありますが、それがどれほど速いかはわかりませんし、後処理も必要です。

于 2013-08-18T06:13:18.743 に答える