2017-01-27 4 views
1

0-1の行列があり、この行列から1つの値のM個の異なるエントリをサンプリングする必要があります。この種の要求に対して、効率的なPython実装がありますか?与えられた要件を満たしながら、行列からのサンプル入力

ベースラインアプローチでは、各反復中に値1のランダムなサンプル1をM回繰り返し、それを保持して位置を保存します。そうでない場合は値1のエントリを見つけるまでこの繰り返しを続けます。次の反復を続けます。良いヒューリスティックではないようです。

+0

あなたはここで何をしていますか?マトリックスとは何ですか?リストのリスト?いくつかの 'numpy'データ構造ですか? –

+0

本当に一度に1つずつしたいですか? http://stackoverflow.com/q/17385419/6876009または多分速いメソッドは、すべてのリストを取得するhttp://stackoverflow.com/q/432112/6876009 – f5r5e5d

+0

@ junapa.arrivillaga、それは2次元numpy配列です画像から生成され、白色および黒色のみを有する。 – user288609

答えて

0

私は間接的にインデックスあなたが持っている場合、交換

ずに入力配列に1(間接)インデックスを取得するためにndx_ndxリストにポップを()を使用してnumpy.nonzero

からの復帰が最終的ndx_ndx空にされることを選びました我々は次のようにそれを行うことができるもの

import numpy as np 


ary = np.random.randint(2, size=(20, 20)) 

# get the indices of all of the ones 

ndx_ary_ones = np.nonzero(ary) 

# make a range list for pointing into ndx_ary_ones 

ndx_ndx = list(range(len(ndx_ary_ones[0]))) 

# randomize the order 

np.random.shuffle(ndx_ndx) 

# pop the last ndx_ndx 

a_ran_ndx_ndx = ndx_ndx.pop() 

# get the index tuple for the one in ary that we removed from ndx_ndx 

a_ran_one_ndx = (ndx_ary_ones[0][a_ran_ndx_ndx], 
       ndx_ary_ones[1][a_ran_ndx_ndx]) 

# testing... 

print('ary', ary, '\n') 
print('ndx_ary_ones ', *ndx_ary_ones, sep = '\n') 
print('\n','ndx_ndx[0:10] ', ndx_ndx[0:10], '\n') 

for _ in range (10): 
    a_ran_ndx_ndx = ndx_ndx.pop() 
    a_ran_one_ndx = (ndx_ary_ones[0][a_ran_ndx_ndx], 
        ndx_ary_ones[1][a_ran_ndx_ndx]) 
    print(a_ran_one_ndx, ary[a_ran_one_ndx]) 

ary [[0 0 0 ..., 1 1 1] 
[0 1 1 ..., 1 1 1] 
[1 0 0 ..., 1 0 1] 
..., 
[1 1 0 ..., 1 0 1] 
[1 1 0 ..., 1 1 1] 
[1 0 0 ..., 0 0 1]] 

ndx_ary_ones 
[ 0 0 0 ..., 19 19 19] 
[ 3 5 7 ..., 14 15 19] 

ndx_ndx[0:10] [121, 43, 146, 69, 64, 3, 29, 186, 98, 30] 

(7, 12) 1 
(8, 18) 1 
(0, 3) 1 
(10, 2) 1 
(18, 18) 1 
(17, 7) 1 
(15, 14) 1 
(4, 11) 1 
(10, 1) 1 
(4, 4) 1 
0

の全てを得:最初[X、Y] = 1行列Aの全ての(x、y)タプル(インデックス)を取得。そのようなインデックスがk個存在するようにする。今度は、k面の偏ったダイスをM回転がす(関数randint(1,k)の一様分布からサンプルをシミュレートすることができる)。置換したサンプル(行列の同じ位置を複数回選択できます)を望む場合は、関数のM個の呼び出しで行うことができます。そうでなければ、繰り返しのあるサンプル(繰り返しが許可されていない)については、選択した位置を追跡し、次にダイビングを投げる前に配列からそれらのインデックスを削除する必要があります。

関連する問題