2016-08-20 22 views
4

私のgoogle-fuが失敗しました! arr2dの各行についてnumpy配列で値をランダムに列方向に割り当てる方法

arr2d = np.zeros((10,10)) 

Iは1に3つのランダム列を割り当てる、次のよう Iは0に初期10×10 numpyの配列を有します。

for row in arr2d: 
    rand_cols = np.random.randint(0,9,3) 
    row[rand_cols] = 1 

出力:

array([[ 0., 0., 0., 0., 0., 0., 1., 1., 1., 0.], 
    [ 0., 0., 0., 0., 1., 0., 0., 0., 1., 0.], 
    [ 0., 0., 1., 0., 1., 1., 0., 0., 0., 0.], 
    [ 0., 0., 0., 0., 1., 1., 1., 0., 0., 0.], 
    [ 1., 0., 0., 1., 1., 0., 0., 0., 0., 0.], 
    [ 1., 0., 1., 1., 0., 0., 0., 0., 0., 0.], 
    [ 0., 1., 0., 0., 0., 0., 1., 0., 1., 0.], 
    [ 0., 0., 1., 0., 1., 0., 0., 0., 1., 0.], 
    [ 1., 0., 0., 0., 0., 0., 1., 1., 0., 0.], 
    [ 0., 1., 0., 0., 1., 0., 0., 1., 0., 0.]]) 

numpyのまたは配列のインデックスを活用する方法はあります/スライスは、よりに同じ結果を達成するために、私は次のようにループを使用してそれを行うことができますよPython /エレガントな方法(コードの1行または2行にあることが望ましい)?

+2

あなたの行の1つに2つの '1 'しかないことに気付きましたか?これは 'randint(0,9,3)'が繰り返し値を持つサンプルを生成する場合に起こります。それはあなたが欲しいものですか? –

+0

それで、いずれのソリューションもあなたのために機能しましたか? – Divakar

答えて

0

パフォーマンス面ではどれくらい良いか分かりませんが、かなり簡潔です。

arr2d[:, :3] = 1 
map(np.random.shuffle, arr2d) 
+0

これは、すべての行で同じ列を選択します。 – user2357112

+0

それを指摘してくれてありがとう、私は質問を誤解した。 – zarak

0

回答は、this questionから反復しない乱数を生成するために使用します。 Pythonのrandomモジュールのrandom.sampleまたはnp.random.choiceを使用できます。

だから、あなたのコードをほんの少し修正:

>>> import numpy as np 
>>> for row in arr2d: 
...  rand_cols = np.random.choice(range(10), 3, replace=False) 
...  # Or the python standard lib alternative (use `import random`) 
...  # rand_cols = random.sample(range(10), 3) 
...  row[rand_cols] = 1 
... 
>>> arr2d 
array([[ 0., 0., 0., 0., 0., 1., 1., 1., 0., 0.], 
     [ 0., 0., 1., 0., 0., 0., 0., 0., 1., 1.], 
     [ 1., 0., 0., 0., 0., 0., 1., 0., 1., 0.], 
     [ 0., 0., 1., 1., 0., 0., 1., 0., 0., 0.], 
     [ 0., 0., 0., 0., 0., 0., 1., 0., 1., 1.], 
     [ 0., 0., 1., 1., 0., 0., 1., 0., 0., 0.], 
     [ 0., 0., 0., 0., 1., 1., 1., 0., 0., 0.], 
     [ 0., 1., 0., 0., 1., 1., 0., 0., 0., 0.], 
     [ 0., 1., 0., 0., 1., 0., 0., 0., 1., 0.], 
     [ 0., 0., 1., 1., 0., 0., 0., 0., 1., 0.]]) 

私はあなたが本当にここ列スライスを活用し、あなたがから無作為化配列を生成している場合を除きに、1に値を設定することができるとは思いませんスクラッチ。これは、各行のインデックスがランダムであるためです。です。読みやすさのためにループの形にしておきます。

+1

FYI: 'numpy.random.choice(10、size = 3、replace = False)'を使って非繰り返し乱数を生成することができます。これはあなたがリンクした質問に対する回答の1つに記載されています。 –

+0

@WarrenWeckesser私は注意しましたが、2番目の結果であるため、私はそれを含めませんでした。私は代わりとしてそれを追加します。ありがとう! – Praveen

+1

実際、振り返ってみると、非常に似通った2つのインポートを避けるためには、おそらく 'np.random'を使う方が良いでしょう。 – Praveen

2

あなたがarr2darr2d = np.zeros((10,10))で初期化したら、あなたはtwo-linerそうのようにベクトル化されたアプローチを使用することができます - あなたがそのようにそれを好めば

# Generate random unique 3 column indices for 10 rows 
idx = np.random.rand(10,10).argsort(1)[:,:3] 

# Assign them into initialized array 
arr2d[np.arange(10)[:,None],idx] = 1 

またはワンライナーのためにすべてでけいれん -

arr2d[np.arange(10)[:,None],np.random.rand(10,10).argsort(1)[:,:3]] = 1 

サンプル実行 -

In [11]: arr2d = np.zeros((10,10)) # Initialize array 

In [12]: idx = np.random.rand(10,10).argsort(1)[:,:3] 

In [13]: arr2d[np.arange(10)[:,None],idx] = 1 

In [14]: arr2d # Verify by manual inspection 
Out[14]: 
array([[ 0., 1., 0., 1., 0., 0., 0., 0., 1., 0.], 
     [ 0., 0., 0., 0., 1., 1., 0., 0., 1., 0.], 
     [ 0., 0., 0., 0., 0., 1., 0., 1., 0., 1.], 
     [ 0., 1., 1., 0., 0., 0., 0., 0., 1., 0.], 
     [ 0., 0., 1., 1., 0., 0., 0., 1., 0., 0.], 
     [ 1., 0., 0., 0., 0., 1., 0., 0., 1., 0.], 
     [ 0., 0., 0., 1., 0., 0., 0., 1., 0., 1.], 
     [ 1., 0., 0., 0., 0., 0., 1., 0., 1., 0.], 
     [ 1., 0., 0., 1., 0., 0., 0., 0., 1., 0.], 
     [ 0., 1., 0., 1., 0., 0., 0., 0., 0., 1.]]) 

In [15]: arr2d.sum(1) # Verify by counting ones in each row 
Out[15]: array([ 3., 3., 3., 3., 3., 3., 3., 3., 3., 3.]) 

注:パフォーマンスをお探しの場合は、にリストされているように、np.argpartitionに基づいてアプローチすることをお勧めします。

+0

本当にクールです。これらの2行のコードにはたくさんの賢さが詰まっています。 – zarak

+2

@ zarak元のアイデアはこの投稿から来ました - http://stackoverflow.com/a/29156976/3293881。ルーズなアプローチに対するスピードアップは以下の通りです:http://stackoverflow.com/a/31958263/3293881 – Divakar

関連する問題