2011-03-03 13 views
0

私は数値のリストを持っていますが、サイズの異なる対応する配列に分割する必要がありますが、分割する配列のすべての組み合わせを構成します。たとえば、配列a=[1,2,3,4,5]を持っていて、サイズ3とそれ以外の2の1つの配列に分割したいとします。配列を2つの配列にランダム化する

したがって、各配列を保持する2つの配列を作成することを考えていました。 3とサイズ2の配列を使用して、それらを一致させてからテストを実行することができます。 (それは統計クラスなので、より良いscipyまたはnumpyの実装があれば、私はそれらを使用して移動したいと思っているので、私はそれを聞くのが大好きです、最後に私は異なる配列)

しかし、ここで私のコードのために、それは事前に

import itertools 


#defines the array of numbers and the two columns 
number = [53, 64, 68, 71, 77, 82, 85] 
col_one = [] 
col_two = [] 

#creates an array that holds the first four 
results = itertools.combinations(number,4) 

for x in results: 
col_one.append(list(x)) 

print col_one 


#attempts to go through and remove those numbers in the first array 
#and then add that array to col_two 
for i in range(len(col_one)): 
holder = number 
for j in range(4): 
    holder.remove(col_one[i][j]) 
col_two.append(holder) 

おかげ

EDITである:それはめちゃくちゃコードの間隔と思われる - 私はもののときに私の間隔はokです、あなたを保証コードを実行するholderからアイテムを削除することはできません。

答えて

0

私はあなたのコードをテストしたところ、問題が見えます。このコードでは、

for i in range(len(col_one)): 
    holder = number 
    for j in range(4): 
     holder.remove(col_one[i][j]) 
    col_two.append(holder) 

ラインholder = numbernumberをコピーしませんが、それだけでnumber 2番目の名前、holderを与えます。その後、holderから物を取り除くと、それらもnumberから削除されます。そのため、ループが再び回ったとき、数字の数は4つ少なくなります。広告無限

あなたは数のコピーを作りたい:

for i in range(len(col_one)): 
    holder = list(number) 
    for j in range(4): 
     holder.remove(col_one[i][j]) 
    col_two.append(holder) 

これはholderと呼ばれるnumberから新しいリストを作成します。現在holderのみが変更されています。

holder = number[:] 

でも動作します。

ます。また、インデックス変数を回避することにより、forのポテンシャルをフルに使用する必要があります。

for num_list in col_one: 
    holder = list(number) 
    for num in num_list: 
     holder.remove(num) 
    col_two.append(holder) 

これは同じことを行い、より高速なブートにおそらく読んでする方が簡単です。

次に、次のステップとして、リストの補完を行います。これはネストされたループを避けるための素晴らしい方法です。

for c1_list in col_one: 
    c2_list = [n for n in number if n not in c1_list] 
    col_two.append(c2_list) 

これは上記と同じことです。あなたも、このワンライナーにすることができます。

col_two = [[n for n in number if n not in c1_list] for c1_list in col_one] 

はすべて一緒にそれを組み合わせる:

number = [53, 64, 68, 71, 77, 82, 85] 
col_one = list(itertools.combinations(number, 4)) 
col_two = [[n for n in number if n not in c1_list] for c1_list in col_one] 
+0

私はそれをお詫びしますが、助けてくれてありがとう。 – tshauck

1

を、それがための指標を計算するためにsetを使用して、このソリューションは、大きな配列のために、より効率的でなければなりません二番目の配列、およびメモリを予め割り当て:

import scipy as sp 
import itertools 

number = sp.array([53, 64, 68, 71, 77, 82, 85]) 
len_number = len(number) 

# number of combinations 
ncomb = sp.comb(len_number, 4) 
# pre-allocate memory 
col_one = sp.empty((ncomb, 4)) 
col_two = sp.empty((ncomb, len_number-4)) 

indices = range(len_number) 
indices_set = set(indices) 
for i, idx in enumerate(itertools.combinations(indices, 4)): 
    col_one[i,:] = number[list(idx)] 
    col_two[i,:] = number[list(indices_set.difference(idx))] 

一層効率的な解決策は、長len_number CONTの全てのブール配列を生成することによって得ることができもし可能ならば、私はループ内の所望の統計量を計算し、代わりにそれらを格納することでcol_onecol_twoを格納しないでしょう

col_one[i,:] = number[bool_idx] 
col_two[i,:] = number[sp.logical_not(bool_idx)] 

書くことができるようになり、正確に4 True値を、aining。

関連する問題