3

問題: 10 x 10 のゼロの配列に 10 個の 1、20 個の 2、30 個の 3 をランダムに配置します。

実際に配列を使用する必要はありません。値が存在する位置の座標が必要なだけです。配列の観点から考えると簡単です。

私はこれに対していくつかの解決策を書きましたが、それらはすべて単純ではなく、pythonic ではないようです。誰かが私に洞察を与えてくれることを願っています。私の方法では、0〜99の線形配列を使用し、ランダムに(np.random.choice)10個の値を選択し、それらを配列から削除してから、20個のランダム値を選択しました。その後、線形位置を (y,x) 座標に変換します。

import numpy as np

dim = 10
grid = np.arange(dim**2)

n1 = 10
n2 = 20
n3 = 30

def populate(grid, n, dim):
    pos = np.random.choice(grid, size=n, replace=False)
    yx = np.zeros((n,2))
    for i in xrange(n):
        delPos = np.where(grid==pos[i])
        grid = np.delete(grid, delPos)
        yx[i,:] = [np.floor(pos[i]/dim), pos[i]%dim]
    return(yx, grid)

pos1, grid = populate(grid, n1, dim)
pos2, grid = populate(grid, n2, dim)
pos3, grid = populate(grid, n3, dim)

おまけ 1 を入力するときに、それらすべてを「配列」の半分に配置したいとします。私の方法(グリッド[dim ** 2/2 :]からのサンプリング)を使用してそれを行うことができますが、他の提案で同じことを行う方法がわかりません。

4

3 に答える 3

3

すべての座標のリストを作成し、shuffleそのリストから最初の 60 個 (10 + 20 + 30) を取得できます。

>>> import random
>>> coordinates = [(i, j) for i in xrange(10) for j in xrange(10)]
>>> random.shuffle(coordinates)
>>> coordinates[:60]
[(9, 5), (6, 9), (1, 5), ..., (0, 2), (5, 9), (2, 6)]

次に、最初の 10 個を使用して 10 個の値を挿入し、次の 20 個を使用して 20 個の値を挿入し、残りを使用して 30 個の値を挿入できます。

于 2013-10-30T16:02:02.223 に答える
3

配列を生成するには、 を使用できますnumpy.random.choice

np.random.choice([0, 1, 2, 3], size=(10,10), p=[.4, .1, .2, .3])

その後、座標に変換できます。numpy.random.choice確率 を使用してランダム サンプルを生成するため、 で正確な比率pを取得できるとは限らないことに注意してください。p

追加

1配列の特定の側にすべての を配置したい場合は、2 つのランダムな配列を生成してからhstackそれらを生成できます。トリックは、両側の各数値の確率をわずかに変更することです。

In [1]: import numpy as np
In [2]: rem = .1/3 # amount to de- / increase the probability for non-1s
In [3]: A = np.random.choice([0, 1, 2, 3], size=(5, 10),
                              p=[.4-rem, .2, .2-rem, .3-rem])
In [4]: B = np.random.choice([0, 2, 3], size=(5, 10), p=[.4+rem, .2+rem, .3+rem])
In [5]: M = np.hstack( (A, B) )
In [6]: M
Out[1]: 
array([[1, 1, 3, 0, 3, 0, 0, 1, 1, 0, 2, 2, 0, 2, 0, 2, 3, 3, 2, 0],
       [0, 3, 3, 3, 3, 0, 1, 3, 1, 3, 0, 2, 3, 0, 0, 0, 3, 3, 2, 3],
       [1, 0, 0, 0, 1, 0, 3, 1, 2, 2, 0, 3, 0, 3, 3, 0, 0, 3, 0, 0],
       [3, 2, 3, 0, 3, 0, 1, 2, 3, 2, 0, 0, 0, 0, 3, 2, 0, 0, 0, 3],
       [3, 3, 0, 3, 3, 3, 1, 3, 0, 3, 0, 2, 0, 2, 0, 0, 0, 3, 3, 3]])

ここでは、すべて1s を左側に置いているので1、各数字の確率を 2 倍にし、確率を均等に減らします。反対側を作成するときも同じロジックが適用されます。

于 2013-10-30T16:01:02.423 に答える
0

これがもはや「Pythonic」であるかどうかはわかりませんが、シメオンの答えの一部を使用して思いついたものを次に示します。

import random

dim = 10
n1 = 10
n2 = 20
n3 = 30

coords = [[i,j] for i in xrange(dim) for j in xrange(dim)]

def setCoords(coords, n):
    pos = []
    for i in xrange(n):
        random.shuffle(coords)
        pos.append(coords.pop())
    return(coords, pos)

coordsTmp, pos1 = setCoords(coords[dim**2/2:], n1)
coords = coords[:dim**2/2] + coordsTmp
coords, pos2 = setCoords(coords, n2)
coords, pos3 = setCoords(coords, n3)
于 2013-10-30T19:16:21.727 に答える