2016-11-29 1 views
5

私はこのように構成された2D座標のリストを持っている:coo[0]は最初のタプルに格納された座標でリストやタプルのリストからオブジェクトのランダムなペアを選択する方が効率的な方法はどれですか?

coo = [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0)] 

私は2つを選択したいと思います異なるランダム座標。私はそれを行うためのより高速な方法がある場合は、この操作を私が思っていた1'000'000回繰り返す必要があるため

import numpy as np 
rndcoo1 = coo[np.random.randint(0,len(coo))] 
rndcoo2 = coo[np.random.randint(0,len(coo))] 
if rndcoo1 != rndcoo2: 
    #do something 

しかし:私はもちろん、この方法を使用することができます。 np.random.choice()は2次元アレイには使用できません。使用できる代替手段はありますか?

+1

は '実際numpyのアレイをcoo'ていますか? 'np.random.choice'の代わりに' random.choice'を試しましたか?また、 'rndcoo1'と' rndcoo2'は区別されるべきですか? –

+0

@ G M rndcoo1、rndcoo2 = [coo [np.random.choice(len(coo))]は範囲内の__(2)] –

+0

@tobias_k必要に応じてリストにすることができます。実際には私はrandom.choiceを使用することはできませんでしたし、それは良いようです。私は2つの異なる座標を同じにすることはできませんを選択する必要があります。 –

答えて

6
import random 
result = random.sample(coo, 2) 

は、期待される出力を提供します。そして、おそらくPythonで手に入るほど高速です。

0

coo実際には等間隔の座標ですか?もしそうなら、あなたはちょうどこのようM 2D座標をサンプリングすることができます:もちろん

import numpy 

N = 100 
M = 1000000 
coo = numpy.random.randint(0, N, size=(M, 2)) 

あなたもバイアスと異なるステップサイズとオフセットを考慮して加算と乗算を使用して配布を拡張することができます。

メモリの制限が大きいMを実行している場合は、もちろん小さいサイズをサンプルすることも、size=2を使用して2つの値の配列を1つだけサンプリングすることもできます。

1

この記事に掲載されているのは、何度も反復処理を繰り返すことなく、1回の処理で多数の反復をランダムに選択できるベクトル化アプローチです。このアイデアはnp.argpartitionを使用し、this postからインスピレーションを受けています。

ここでの実装です -

def get_items(coo, num_items = 2, num_iter = 10): 
    idx = np.random.rand(num_iter,len(coo)).argpartition(num_items,axis=1)[:,:2] 
    return np.asarray(coo)[idx] 

二次元が各繰り返しで作られている選択肢の数と最後であること、我々は最初の次元は、反復の数であることを3D配列を返すことに注意してくださいdimensionは各タプルの長さです。

サンプルランはもう少し鮮明な画像を提示しなければならない - @freakish's postに記載されているrandom.sampleとルーピー実装を比較

In [55]: coo = [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0)] 

In [56]: get_items(coo, 2, 5) 
Out[56]: 
array([[[2, 0], 
     [1, 1]], 

     [[0, 0], 
     [1, 1]], 

     [[0, 2], 
     [2, 0]], 

     [[1, 1], 
     [1, 0]], 

     [[0, 2], 
     [1, 1]]]) 

ランタイム試験 -

In [52]: coo = [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0)] 

In [53]: %timeit [random.sample(coo, 2) for i in range(10000)] 
10 loops, best of 3: 34.4 ms per loop 

In [54]: %timeit get_items(coo, 2, 10000) 
100 loops, best of 3: 2.81 ms per loop 
+0

優秀!非常に面白い仕事! –

関連する問題