13

NumPy 配列からセルをランダムに選択し、それらに対して何らかの処理を行う必要があるいくつかのモデリング ルーチンを NumPy で作成しています。すべてのセルは置換せずに選択する必要があります (セルを選択すると、再度選択することはできませんが、最後までにすべてのセルを選択する必要があります)。

これを行う良い方法を見つけることができるIDLから移行していますが、NumPyにもこれを行う良い方法があると思います。何を提案しますか?

更新: 2D 配列でこれを実行しようとしているため、2D インデックスのセットを取得しようとしていると述べるべきでした。

4

6 に答える 6

20

元のアレイを使用するのはどうですか、それでも必要な場合はどうでしょうかnumpy.random.shufflenumpy.random.permutation

配列をインプレースで変更する必要がある場合は、次のようなインデックス配列を作成できます。

your_array = <some numpy array>
index_array = numpy.arange(your_array.size)
numpy.random.shuffle(index_array)

print your_array[index_array[:10]]
于 2010-10-08T13:52:26.110 に答える
2

@ WoLpHからの素敵な回答を拡張する

2D配列の場合、インデックスについて何を知りたいか、または知る必要があるかに依存すると思います。

次のようなことができます。

data = np.arange(25).reshape((5,5))

x, y  = np.where( a = a)
idx = zip(x,y)
np.random.shuffle(idx)

また

data = np.arange(25).reshape((5,5))

grid = np.indices(data.shape)
idx = zip( grid[0].ravel(), grid[1].ravel() )
np.random.shuffle(idx)

次に、リストidxを使用して、ランダムに並べられた 2D 配列インデックスを必要に応じて反復処理し、data変更されていない からそのインデックスの値を取得できます。

itertools.product:このツール セットに慣れている場合は、ランダムに並べられたインデックスを生成することもできます。

于 2010-10-08T15:17:51.523 に答える
1

サイズが 8x3 のデータ ポイントの配列があるとします。

data = np.arange(50,74).reshape(8,-1)

あなたが言うように、すべてのインデックスを2次元ペアとして本当にサンプリングしたい場合、私が考えることができる最もコンパクトな方法は次のとおりです。

#generate a permutation of data's size, coerced to data's shape
idxs = divmod(np.random.permutation(data.size),data.shape[1])

#iterate over it
for x,y in zip(*idxs): 
    #do something to data[x,y] here
    pass

ただし、一般的には、単に 2 次元配列をシャッフルするために 2 次元配列としてアクセスする必要はなく、その場合はさらにコンパクトにすることができます。配列に対して 1 次元ビューを作成するだけで、インデックスのラングリングを節約できます。

flat_data = data.ravel()
flat_idxs = np.random.permutation(flat_data.size)
for i in flat_idxs:
    #do something to flat_data[i] here
    pass

これにより、必要に応じて2次元の「元の」配列が並べ替えられます。これを確認するには、次を試してください。

 flat_data[12] = 1000000
 print data[4,0]
 #returns 1000000
于 2011-01-15T07:29:42.537 に答える
1

numpy バ​​ージョン 1.7 以降を使用している人は、組み込み関数も使用できますnumpy.random.choice

于 2013-08-11T22:19:28.253 に答える
1

random.sample0 .. A.size で重複のない int を生成するために使用し、それらをインデックス ペアに分割します。

import random
import numpy as np

def randint2_nodup( nsample, A ):
    """ uniform int pairs, no dups:
        r = randint2_nodup( nsample, A )
        A[r]
        for jk in zip(*r):
            ... A[jk]
    """
    assert A.ndim == 2
    sample = np.array( random.sample( xrange( A.size ), nsample ))  # nodup ints
    return sample // A.shape[1], sample % A.shape[1]  # pairs


if __name__ == "__main__":
    import sys

    nsample = 8
    ncol = 5
    exec "\n".join( sys.argv[1:] )  # run this.py N= ...
    A = np.arange( 0, 2*ncol ).reshape((2,ncol))

    r = randint2_nodup( nsample, A )
    print "r:", r
    print "A[r]:", A[r]
    for jk in zip(*r):
        print jk, A[jk]
于 2010-10-08T17:36:27.717 に答える