2016-03-15 20 views
7

私はいくつかの数字を順序付けるためにpythonを使用しています。私は値(4,8,16,32,64など)を入力し、数値の配列を作成し、シーケンスを並べ替えることができる関数を作成したいと考えています。forループ(Python)の動的数を繰り返します。

I値= 4のための配列を決定する方法を詳細図面を追加し、その値8.

= 4アレイ(X = [0、1、2、3])が分割されるべきです2つ([0,1]と[2,3])で配列し、各配列([0,2,1,3])の最初の数に基づいて結合します。 (X = [0、1、2、3、4、5、6、7])は、2つ([0、1、2、3に分割されるべき値= 8アレイについて

Figure with sequence for value = 4

]および[4,5,6,7])。両方のアレイを[0,1]、[2,3]、[4,5,6,7]に[4,5]と[6、 7])。次に、各配列の最初の番号と2番目の配列の配列([0、4,2,6,1,5,3,7])のシーケンスに基づいて配列を結合する必要があります。

Figure for sequence for value = 8

私は(動的ループのネストされた)再帰を処理する方法がわかりません。私は配列を分割することによって作成された各brachをループしようとしています。私はitertoolsと再帰(Function with varying number of For Loops (python))を調べましたが、私はそれを動作させることができませんでした。以下、これまでの私のアプローチを示すコードを追加しました。

ご迷惑をおかけして申し訳ありません。私はまた、シーケンスを決定するために他のアイデアを公開しています。

私はpython 2.7.6とnumpyを使用しています。

コード:

import numpy 
value = 4 
a = [] 
x = numpy.arange(value) 
y = numpy.array_split(x, 2) 
for i in range(2): 
    for j in y: 
     a.append(j.tolist()[i]) 
print(a) 

出力:

[0, 2, 1, 3] 

コード:

import numpy 
value = 8 
a = [] 
x = numpy.arange(value) 
y = numpy.array_split(x, 2) 
for i in range(2): 
    for h in range(2): 
     for j in y: 
     z = numpy.array_split(j, 2) 
       a.append(z[h][i]) 
    print(a) 

出力:

[0, 4, 2, 6, 1, 5, 3, 7] 

値= 16の出力は[0、8、4、12、2、10、6、14、1、9、5、13、3、11、7 15]でなければなりません。

+0

あなたが必要ですnumpyの解決策?これは普通のPythonで行うことができると私は思う。 –

+0

あなたが必要とするのは、数値のバイナリ形式を取ってantialphabeticallyソートすることだ – Ilja

答えて

2

ここnp.transposereshaping使用NumPythonic方法です -

def seq_pow2(N): 
    shp = 2*np.ones(np.log2(N),dtype=int) 
    return np.arange(N).reshape(shp).transpose(np.arange(len(shp))[::-1]).ravel() 

.transpose(np.arange(len(shp))[::-1].Tに単純化することに注意してください、私たちは簡略化されたバージョンだろう -

def seq_pow2(N): 
    shp = 2*np.ones(np.log2(N),dtype=int) 
    return np.arange(N).reshape(shp).T.ravel() 

をあなたはさらに簡素化し、交換することができますravel/flatteningfortranとのような列の主要な順序で実行することによって全体を転置する

def seq_pow2(N): 
    shp = 2*np.ones(np.log2(N),dtype=int) 
    return np.arange(N).reshape(shp).ravel('F') 

サンプルの実行 - -

In [43]: seq_pow2(4) 
Out[43]: array([0, 2, 1, 3]) 

In [44]: seq_pow2(8) 
Out[44]: array([0, 4, 2, 6, 1, 5, 3, 7]) 

In [45]: seq_pow2(16) 
Out[45]: array([ 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15]) 
1

これを行う最も簡単な方法があるのにない numpyのをいくつかの配列操作を行うが、forループを使用し、最終的に私たちを導くために。

N = 8 
pow2 = np.log2(N) 
out = np.arange(N).reshape([2]*pow2).transpose(np.arange(pow2)[::-1]).flatten() 

    array([0, 4, 2, 6, 1, 5, 3, 7]) 

これがないと、それはnxの長さに対応する2のべき乗であるn次元配列にxを整形です。この再形成の後、各次元の長さは2です。次に、すべての次元を逆にして平坦化して、必要な配列を取得します。

編集

これはDivakar's Solutionと同様のアプローチである、と彼ははるかに簡潔にそれをやってしまったが、私はただ後世のためにここにこれを残しておきます。

2

明確にするためのpython再帰バージョン、:

def rec(n): 
    if n==1 : return [0] 
    l=[0]*n 
    l[::2]=rec(n//2) 
    for i in range (0,n,2) : l[i+1]=l[i]+n//2 
    return l 

結果のバイナリ表現を観察し、

In [6]: rec(16) 
Out[6]: [0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15] 

または、numpyのソリューション:

def rearange(N): 
    u=2**arange(N.bit_length()-1) 
    v=arange(N) 
    bits= u[None,:] & v[:,None] 
    return sum(bits*u[::-1],1) 
関連する問題