2016-08-10 7 views
1

私は長さがnの配列を持っていますが、それからランダムにm要素を選択してその値を反転したいと思います。最も効率的な方法は何ですか?配列からのランダムなフリップmの値

ケースが2つある場合は、m=1ケースが特殊ケースです。それは別々に議論することができ、m=/=1です。

私の試みは、次のとおりです。

import numpy as np 
n = 20 
m = 5 
#generate an array a 
a = np.random.randint(0,2,n)*2-1 
#random choose `m` element and flip it. 
for i in np.random.randint(0,n,m): 
    a[m]=-a[m] 

と仮定mは数十あるとnは何百ものです。

+0

効率を定義します。また、nとmの近似値はどうですか?いくつかの値の中で最も効率的な方法は、他の人にとって最も効率的ではないかもしれません。 – cammil

+0

@cammil編集を参照 – buzhidao

答えて

3

同じ要素を2回以上反転させないように、np.random.choiceでその長さの範囲に一意のインデックスを作成することができます(オプションの引数をFalseに設定します)。次に、単純に入力配列にインデックスを付け、一度に反転させると、望ましい出力が得られます。私は同じ動作をシミュレートするためにnp.argpartitionを使用して探るthis post上に読んで示唆し、np.random_choiceの速いバージョンについては:

idx = np.random.choice(n,m,replace=False) 
a[idx] = -a[idx] 

高速化バージョン - したがって、我々はそうのような実装を持っているでしょう。

+0

'random.choice'と' idx = np.random.randint(0、n、m) 'は同じ要素を生成するのを防ぎます。いい案! – buzhidao

0

実際に値を変更するには、配列のインデックスをmからiに変更する必要があります。 結果:

import numpy as np 
n = 20 
m = 5 
#generate an array a 
a = np.random.randint(0,2,n)*2-1 
print(a) 
#random choose `i` element and flip it. 
for i in np.random.randint(0,n,m): 
    a[i] = -a[i] 

print(a) 

マイ出力:

[ 1 1 -1 -1 1 -1 -1 1 1 -1 -1 1 -1 1 1 1 1 -1 1 -1] 
[ 1 1 -1 -1 -1 -1 1 1 1 -1 -1 1 -1 -1 1 -1 1 -1 -1 -1] 
1

あなたは、配列のインデックスのランダム置換を行い、それらの最初のmを取り、その値を反転することができます

a[np.random.permutation(range(len(a)))[:m]]*=-1 

使い方permutationは、同じインデックスを2回選択しないことを検証します。

+0

これらの操作は左右で異なるインデックスを持っていますか?つまり、 'random.randint() '= - a [random.randint()]'を実行すると、おそらく私たちはその作業をやっていません。インデックスを変更します。 'a [random.randint()] * = -1'を実行すると' random.randint() 'は一度だけ実行されますか? – buzhidao

+0

'randint'は1回だけ実行されます。 –

関連する問題