2016-12-09 18 views
4

バイナリ(0 | 1)のnumpy配列を整数またはバイナリ文字列に変換するショートカットはありますか? F.e.バイナリ(0 | 1)numpyを整数またはバイナリ文字列に変換しますか?

b = np.array([0,0,0,0,0,1,0,1]) 
    => b is 5 

np.packbits(b) 

作品だけ8ビット値のnumpyのは、それが2つの以上8ビット値を生成する9種以上の元素である..if。

ba = bitarray() 
    ba.pack(b.astype(np.bool).tostring()) 
    #convert from bitarray 0|1 to integer 
    result = int(ba.to01(), 2) 

醜いです!!!:

私は現在、やることはある... 1 | 別のオプションは、0の文字列を返すようになります2-poweredレンジアレイとdot-productを使用することでしょう

答えて

5

一つの方法 -

b.dot(2**np.arange(b.size)[::-1]) 

サンプル実行 - また

In [95]: b = np.array([1,0,1,0,0,0,0,0,1,0,1]) 

In [96]: b.dot(2**np.arange(b.size)[::-1]) 
Out[96]: 1285 

、我々は、レンジ・アレイを作成するために、ビット単位の左シフト演算子を使用するので、得ることができます希望の出力はそうです -

b.dot(1 << np.arange(b.size)[::-1]) 

タイミングが注目されている場合 -

In [148]: b = np.random.randint(0,2,(50)) 

In [149]: %timeit b.dot(2**np.arange(b.size)[::-1]) 
100000 loops, best of 3: 13.1 µs per loop 

In [150]: %timeit b.dot(1 << np.arange(b.size)[::-1]) 
100000 loops, best of 3: 7.92 µs per loop 

リバースプロセス

は、バイナリ配列をバック取り出す使用するにはnp.binary_reprnp.fromstringを伴って含む -

In [96]: b = np.array([1,0,1,0,0,0,0,0,1,0,1]) 

In [97]: num = b.dot(2**np.arange(b.size)[::-1]) # integer 

In [98]: np.fromstring(np.binary_repr(num), dtype='S1').astype(int) 
Out[98]: array([1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1]) 
+0

賢い:)私はそれを承認する前に誰かがより良い方法を考え出すことができる場合は、1日か2日待つだろう。 – user1019129

+0

元のバイナリ配列形式に変換するための提案はありますか? – Jonathan

+0

@Jonathan良い質問!以前に追加したはずです。掲示される。 – Divakar

0
def binary_converter(arr): 
    total = 0 
    for index, val in enumerate(reversed(arr)): 
     total += (val * 2**index) 
    print total 


In [14]: b = np.array([1,0,1,0,0,0,0,0,1,0,1]) 
In [15]: binary_converter(b) 
1285 
In [9]: b = np.array([0,0,0,0,0,1,0,1]) 
In [10]: binary_converter(b) 
5 

または

b = np.array([1,0,1,0,0,0,0,0,1,0,1]) 
sum(val * 2**index for index, val in enumerate(reversed(b))) 
0

変換にnumpyを使用すると、64ビット符号付きバイナリの結果に制限されます。あなたが本当にnumpyのを使用したいと64ビットの制限はあなたのために働く場合はnumpyのを使用してより高速な実装は次のとおりです。

import numpy as np 
def bin2int(bits): 
    return np.right_shift(np.packbits(bits, -1), bits.size).squeeze() 

あなたがnumpyのを使用している場合には、速さを気に通常ので> 64ビットのため、その後最速の実装結果である:

import gmpy2 
def bin2int(bits): 
    return gmpy2.pack(list(bits[::-1]), 1) 

あなたはgmpy2への依存をつかむしたくない場合は、これは少し遅いですが、依存関係はありませんし、> 64ビットの結果をサポートしています。

def bin2int(bits): 
    total = 0 
    for shift, j in enumerate(bits[::-1]): 
     if j: 
      total += 1 << shift 
    return total 

Oをbservantは**の代わりに< <演算子を使用しているという主な違いをもって、この質問に対する他の回答といくつかの類似点に注意します。これは私のテストでスピードの大幅な向上につながりました。

関連する問題