116

私はPythonで大きなスクリプトを持っています。私は他の人のコードに触発されたので、numpy.randomモジュールをいくつかの目的(たとえば、二項分布から取得した乱数の配列を作成するため)に使用し、他の場所ではモジュールを使用することになりましたrandom.random

誰かが2つの主な違いを教えてもらえますか?2つのそれぞれのドキュメントWebページを見ると、もっと多くの方法があるように思えますnumpy.randomが、乱数の生成がどのように異なるのかはわかりません。

私が尋ねている理由は、デバッグのためにメインプログラムをシードする必要があるためです。しかし、インポートするすべてのモジュールで同じ乱数ジェネレーターを使用しないと機能しません。これは正しいですか?

また、別の投稿で、を使用しないことについての議論を読んだのですが、numpy.random.seed()なぜこれがそんなに悪い考えなのかよくわかりませんでした。なぜそうなのか、誰かに説明してもらえれば幸いです。

4

4 に答える 4

141

あなたはすでに多くの正しい観察をしました!

両方のランダムジェネレーターをシードする場合を除いて、長期的にはどちらか一方のジェネレーターを選択する方が簡単です。ただし、両方を使用する必要がある場合は、はい、両方をシードする必要があります。これは、これらが互いに独立して乱数を生成するためです。

の場合numpy.random.seed()、主な問題は、スレッドセーフではないことです。つまり、2つの異なるスレッドが同時に関数を実行している場合は動作が保証されないため、実行スレッドが多数ある場合は安全に使用できません。スレッドを使用しておらず、将来このようにプログラムを書き直す必要がないと合理的に予想できる場合は、numpy.random.seed()問題ないはずです。将来スレッドが必要になる可能性があると疑う理由がある場合は、長期的には、提案どおりに実行し、クラスのローカルインスタンスを作成するnumpy.random.Random方がはるかに安全です。私が知る限り、random.random.seed()スレッドセーフです(または、少なくとも、反対の証拠は見つかりませんでした)。

numpy.randomライブラリには、科学研究で一般的に使用されるいくつかの追加の確率分布と、ランダムデータの配列を生成するための便利な関数がいくつか含まれています。random.randomライブラリはもう少し軽量であり、科学的な研究や統計に関する他の種類の作業を行っていない場合は問題ないはずです。

それ以外の場合は、どちらもメルセンヌツイスターシーケンスを使用して乱数を生成します。どちらも完全に決定論的です。つまり、いくつかの重要な情報を知っていれば、次に来る数字を絶対的に確実に予測できます。このため、numpy.randomもrandom.randomも、深刻な暗号化の使用には適していません。ただし、シーケンスが非常に長いため、データをリバースエンジニアリングしようとする人のことを心配していない場合は、どちらも乱数を生成するのに適しています。これは、乱数をシードする必要がある理由でもあります。毎回同じ場所から開始すると、常に同じ乱数のシーケンスが得られます。

ちなみに、暗号化レベルのランダム性が必要な場合は、シークレットモジュールを使用する必要がありますまた、Python 3.6より前のバージョンのPythonを使用している場合は、Crypto.Randomなどを使用する必要があります。

于 2011-08-11T17:56:07.223 に答える
12

Python for Data Analysisから、このモジュールは、さまざまな種類の確率分布からサンプル値の配列全体を効率的に生成するための関数でnumpy.randomPythonを補完します。random

対照的に、Pythonの組み込みrandomモジュールは、一度に1つの値のみをサンプリングしますが、numpy.random非常に大きなサンプルをより高速に生成できます。IPythonマジック関数を使用%timeitすると、どのモジュールがより高速に実行されるかを確認できます。

In [1]: from random import normalvariate
In [2]: N = 1000000

In [3]: %timeit samples = [normalvariate(0, 1) for _ in xrange(N)]
1 loop, best of 3: 963 ms per loop

In [4]: %timeit np.random.normal(size=N)
10 loops, best of 3: 38.5 ms per loop
于 2017-05-08T01:37:05.817 に答える
3

シードのソースと使用される分散プロファイルが出力に影響を与えます-暗号のランダム性を探している場合、os.urandom()からのシードは、デバイスのチャタリング(イーサネットまたはディスク)からほぼ実際のランダムバイトを取得します(つまり、/ BSDのdev/random)

これにより、シードを与えて決定的な乱数を生成することを回避できます。ただし、ランダム呼び出しを使用すると、数値を分布に適合させることができます(私が科学的ランダム性と呼んでいるもの-最終的に必要なのは、乱数のベルカーブ分布だけです。numpyはこれを導き出すのに最適です。

そうです、1つのジェネレーターに固執しますが、必要なランダムを決定します。ランダムですが、分散曲線から適切に、または量子デバイスなしで取得できる限りランダムです。

于 2011-08-11T18:25:33.970 に答える
0

randint(a, b)メソッドがとの両方numpy.randomに存在することに驚いたrandomが、それらは上限に対して異なる振る舞いをしている。

random.randint(a, b)のようなランダムな整数Nを返しますa <= N <= b。のエイリアスrandrange(a, b+1)b包括的です。ランダムなドキュメント

ただし、を呼び出すとnumpy.random.randint(a, b)、low(包括的)からhigh(排他的)に戻ります。ずんぐりしたドキュメント

于 2021-03-06T22:58:29.647 に答える