一貫して同じランダムなnumpy配列を作成します


89

別の開発者が、-1,0または1の値を持つ形状(100,2000)のnp配列を返すコードを完成させるのを待っています。

それまでの間、同じ特性の配列をランダムに作成して、開発とテストをすぐに開始できるようにしたいと思います。重要なのは、このランダムに作成された配列を毎回同じにしたいので、プロセスを再実行するたびに値が変化し続ける配列に対してテストしないようにすることです。

このように配列を作成できますが、毎回同じになるように配列を作成する方法はありますか。オブジェクトをピクルスにしてピクルスを外すことができますが、別の方法があるかどうか疑問に思います。

r = np.random.randint(3, size=(100, 2000)) - 1

回答:


84

乱数ジェネレーターに固定値をシードするだけです。

numpy.random.seed(42)

このようにして、常に同じ乱数シーケンスを取得します。


43
私がnumpy.random.seed()注意を払っていなかったときに誰かが関数に忍び込んだ。:-)元のモジュールから意図的に除外しました。独自のインスタンスを使用して、RandomStateそれらのオブジェクトを渡すことをお勧めします。
ロバートカーン

6
Robertはnumpyの主要な貢献者です。私たちは彼の意見にいくらかの重みを与えるべきだと思います。
非推奨

10
@deprecated:Robertの仕事に感謝していますが、彼の仕事は、推奨の根拠を与えることに代わるものではありません。さらに、の使用numpy.random.seed()が推奨されない場合は、ドキュメントに記載する必要があります。どうやら、NumPyの他の貢献者はロバートの意見を共有していません。攻撃はまったく意図されていません、私はただ興味があります。
Sven Marnach 2011年

13
これは、Python標準ライブラリのオブジェクトrandom.seedを使用するrandom.Random場合と使用する場合と同じです。random.seedまたはを使用すると、コードと呼び出しているコード、または同じセッションで実行されているコードの両方に、すべてのランダムインスタンスnumpy.random.seedがシードされます。それらが実際にランダムであることに依存している場合、問題が発生し始めます。ランダムシードを設定するコードをデプロイすると、セキュリティの脆弱性が発生する可能性があります。
asmeurer 2014年

3
@asmeurerセキュリティの目的で疑似乱数ジェネレータを使用している人は、おそらく自分が何をしているのかわからないでしょう。
JAB 2016

191

numpy.random.RandomState()選択したシードを使用して、の独自のインスタンスを作成します。numpy.random.seed()独自のRandomStateインスタンスを渡さない柔軟性のないライブラリを回避する場合を除いて、使用しないでください。

[~]
|1> from numpy.random import RandomState

[~]
|2> prng = RandomState(1234567890)

[~]
|3> prng.randint(-1, 2, size=10)
array([ 1,  1, -1,  0,  0, -1,  1,  0, -1, -1])

[~]
|4> prng2 = RandomState(1234567890)

[~]
|5> prng2.randint(-1, 2, size=10)
array([ 1,  1, -1,  0,  0, -1,  1,  0, -1, -1])

7
あなたの推薦の根拠はありますか?何が問題になっていnumpy.random.seed()ますか?スレッドセーフではないことは知っていますが、スレッドセーフが必要ない場合は非常に便利です。
Sven Marnach 2011

52
それは主に良い習慣を形成することです。今は独立したストリームは必要ないかもしれませんが、Sven-今から6か月は必要かもしれません。から直接メソッドを使用するようにライブラリを作成する場合numpy.random、後で独立したストリームを作成することはできません。また、PRNGストリームを制御することを目的としてライブラリを作成する方が簡単です。ライブラリに入るには常に複数の方法があり、それぞれにシードを制御する方法が必要です。PRNGオブジェクトを渡すことは、に依存するよりもクリーンな方法ですnumpy.random.seed()。残念ながら、このコメントボックスは短すぎて、他の例を含めることができません。:-)
Robert Kern

25
ロバートの理論的根拠を説明する別の方法:numpy.random.seedを使用すると、グローバル変数を使用してPRNG状態が維持され、グローバル変数が不適切であるのと同じ標準的な理由がここに当てはまります。
Robie Basak 2012年

9
PRNGを独立させたい場合は、何もシードしないでください。numpy.random.RandomState()引数なしで使用してください。これにより、そのようなもののためにオペレーティングシステム機能から引き出された一意の値が状態にシードされます(/dev/urandomUNIXマシンおよびそれに相当するWindowsの場合)。numpy.random.RandomState(1234567890)うまくいかない場合は、入力した内容と表示されたエラーメッセージを正確に示してください。
ロバートカーン

5
良い考えではありません。numpy.random.RandomState()最良の結果を得るには、引数なしで使用してください。
ロバートカーン

3

ランダムな状態に依存する他の関数を使用している場合は、シード全体を設定するだけでなく、代わりに関数を作成してランダムな数のリストを生成し、シードを関数のパラメーターとして設定する必要があります。これにより、コード内の他のランダムジェネレーターが妨げられることはありません。

# Random states
def get_states(random_state, low, high, size):
    rs = np.random.RandomState(random_state)
    states = rs.randint(low=low, high=high, size=size)
    return states

# Call function
states = get_states(random_state=42, low=2, high=28347, size=25)

3

ランダムジェネレーターのシードとは何か、コードでいつ/どのように設定されるかを理解することが重要です(シードの数学的意味のわかりやすい説明については、ここを確認してください)。

そのためには、次のようにしてシードを設定する必要があります。

random_state = np.random.RandomState(seed=your_favorite_seed_value)

次に、np.randomからではなく、random_stateから乱数を生成することが重要です。つまり、あなたがすべきこと:

random_state.randint(...)

の代わりに

np.random.randint(...) 

これにより、RandomState()の新しいインスタンスが作成され、基本的にコンピューターの内部クロックを使用してシードが設定されます。


2

明確でない場合に備えて、@ RobertKernの回答に関して何かを明確にしたいと思います。使用する場合でもRandomState、Robertの例のように、numpyランダムメソッドを呼び出すたびに初期化する必要があります。そうしないと、次の結果が得られます。

Python 3.6.9 |Anaconda, Inc.| (default, Jul 30 2019, 19:07:31) 
[GCC 7.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy as np
>>> prng = np.random.RandomState(2019)
>>> prng.randint(-1, 2, size=10)
array([-1,  1,  0, -1,  1,  1, -1,  0, -1,  1])
>>> prng.randint(-1, 2, size=10)
array([-1, -1, -1,  0, -1, -1,  1,  0, -1, -1])
>>> prng.randint(-1, 2, size=10)
array([ 0, -1, -1,  0,  1,  1, -1,  1, -1,  1])
>>> prng.randint(-1, 2, size=10)
array([ 1,  1,  0,  0,  0, -1,  1,  1,  0, -1])
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.