2013-08-18 9 views
8

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

+0

新しいndarrayを作成するには、古いnバッファをバッファとして、dtypeをuint8で作成します。私は、バイトオーダーを処理する最良の方法は、しかし、よく分かりません。 http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.htmlおよびhttp://docs.scipy.org/doc/numpy/user/basics.byteswapping.htmlが役立ちます。 – user2357112

答えて

7

あなたはviewunpackbits

入力してこれを行うことができます:出力

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

a = arange(int(1e6), dtype=uint16)については

[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] 

これは私のマシン

に約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を参照し、必要に応じて提案を適用する必要があります。

+0

ニースの答え、ありがとう! – Cardano

+0

喜んでお答えください:) –

+0

これは、 '' uint8''の範囲の整数に対してのみ機能します。例えば。 '' np.unpackbits(np.array([2 ** 17]、dtype = "uint16")。view( "uint8")) ''は0の配列を返します。 –

1

私はこれでも何の機能も見つけられませんでしたが、おそらくPythonの組み込みstruct.unpackを使用すると、より長いカスタムUIをシフトおよびアンイングするよりも速くカスタム関数を作成できます(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を使用して結果を連結することです。または、アプリケーションに応じて、structured arraysを使用する方が便利です。

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

0

これは、任意のuint の任意の配列(つまり、多次元配列およびuint8 max値より大きい数値の場合)でも機能します。

これは、配列要素の数よりもむしろビット数を循環するので、かなり高速です。

def my_ManyParallel_uint2bits(in_intAr,Nbits): 
    ''' convert (numpyarray of uint => array of Nbits bits) for many bits in parallel''' 
    inSize_T= in_intAr.shape 
    in_intAr_flat=in_intAr.flatten() 
    out_NbitAr= numpy.zeros((len(in_intAr_flat),Nbits)) 
    for iBits in xrange(Nbits): 
     out_NbitAr[:,iBits]= (in_intAr_flat>>iBits)&1 
    out_NbitAr= out_NbitAr.reshape(inSize_T+(Nbits,)) 
    return out_NbitAr 

A=numpy.arange(256,261).astype('uint16') 
# array([256, 257, 258, 259, 260], dtype=uint16) 
B=my_ManyParallel_uint2bits(A,16).astype('uint16') 
# array([[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], 
#  [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], 
#  [0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], 
#  [1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], 
#  [0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]], dtype=uint16) 
関連する問題