2016-05-22 7 views
4

ビットストリングで構成されたnumpy配列を持っています。ビットストリングを整数ベース2に変換していくつかのxorビット演算を実行しようとしています。私はこれでpythonでベース2との文字列を整数に変換することができます:numpyの中でこれを行うには、より速く、より良い方法があれば、私は疑問に思ってビットストリングnumpy配列を整数ベース2に変換する最速の方法

int('000011000',2) 

。私が働いているnumpyの配列の例は、このようなものです:

array([['0001'], 
     ['0010']], 
     dtype='|S4') 

と私はそれを変換することを期待:

array([[1],[2]]) 

答えて

2

一つはに文字列のビットのそれぞれを分離するnp.fromstringを使用することができますuint8タイプの数字を入力して、数学を行列乗算して10進形式に変換/縮小します。したがって、入力配列としてAと、1つのアプローチはそうようになる -

# Convert each bit of input string to numerals 
str2num = (np.fromstring(A, dtype=np.uint8)-48).reshape(-1,4) 

# Setup conversion array for binary number to decimal equivalent 
de2bi_convarr = 2**np.arange(3,-1,-1) 

# Use matrix multiplication for reducing each row of str2num to a single decimal 
out = str2num.dot(de2bi_convarr) 

サンプルラン -

In [113]: A # Modified to show more variety 
Out[113]: 
array([['0001'], 
     ['1001'], 
     ['1100'], 
     ['0010']], 
     dtype='|S4') 

In [114]: str2num = (np.fromstring(A, dtype=np.uint8)-48).reshape(-1,4) 

In [115]: str2num 
Out[115]: 
array([[0, 0, 0, 1], 
     [1, 0, 0, 1], 
     [1, 1, 0, 0], 
     [0, 0, 1, 0]], dtype=uint8) 

In [116]: de2bi_convarr = 2**np.arange(3,-1,-1) 

In [117]: de2bi_convarr 
Out[117]: array([8, 4, 2, 1]) 

In [118]: out = str2num.dot(de2bi_convarr) 

In [119]: out 
Out[119]: array([ 1, 9, 12, 2]) 

別の方法は、np.fromstringを回避することが示唆され得ます。このメソッドでは、最初のintデータ型に変換してから、前のメソッドのstr2numに相当する各桁を区切ります。残りのコードは同じままです。したがって、代替実装は次のようになります -

# Convert to int array and thus convert each bit of input string to numerals 
str2num = np.remainder(A.astype(np.int)//(10**np.arange(3,-1,-1)),10) 

de2bi_convarr = 2**np.arange(3,-1,-1) 
out = str2num.dot(de2bi_convarr) 

ランタイムは

レッツ・時間@Kasramvd's loopy solution含めて問題を解決するために、これまで記載されているすべてのアプローチを、テストします。原因KISS principle

In [198]: # Setup a huge array of such strings 
    ...: A = np.array([['0001'],['1001'],['1100'],['0010']],dtype='|S4') 
    ...: A = A.repeat(10000,axis=0) 


In [199]: def app1(A):    
    ...:  str2num = (np.fromstring(A, dtype=np.uint8)-48).reshape(-1,4) 
    ...:  de2bi_convarr = 2**np.arange(3,-1,-1) 
    ...:  out = str2num.dot(de2bi_convarr)  
    ...:  return out 
    ...: 
    ...: def app2(A):    
    ...:  str2num = np.remainder(A.astype(np.int)//(10**np.arange(3,-1,-1)),10) 
    ...:  de2bi_convarr = 2**np.arange(3,-1,-1) 
    ...:  out = str2num.dot(de2bi_convarr)  
    ...:  return out 
    ...: 

In [200]: %timeit app1(A) 
1000 loops, best of 3: 1.46 ms per loop 

In [201]: %timeit app2(A) 
10 loops, best of 3: 36.6 ms per loop 

In [202]: %timeit np.array([[int(i[0], 2)] for i in A]) # @Kasramvd's solution 
10 loops, best of 3: 61.6 ms per loop 
0

、私はリスト内包を使用して、次のアプローチを提案したいと思います:

>>> np.array([[int(i[0], 2)] for i in a]) 
array([[1], 
     [2]]) 
関連する問題