<?xml version="1.0" encoding="utf-8"?> 
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-us">
    <generator uri="https://gohugo.io/" version="0.152.2">Hugo</generator><title type="html"><![CDATA[Rng on Blog]]></title>
    
    
    
            <link href="https://blog.scientific-python.org/tags/rng/" rel="alternate" type="text/html" title="html" />
            <link href="https://blog.scientific-python.org/tags/rng/atom.xml" rel="self" type="application/atom" title="atom" />
    <updated>2026-04-04T04:32:36+00:00</updated>
    
    
    
    
        <id>https://blog.scientific-python.org/tags/rng/</id>
    
        
        <entry>
            <title type="html"><![CDATA[Best Practices for Using NumPy's Random Number Generators]]></title>
            <link href="https://blog.scientific-python.org/numpy/numpy-rng/?utm_source=atom_feed" rel="alternate" type="text/html" />
            
                <link href="https://blog.scientific-python.org/scientific-python/dev-summit-1-development-guide/?utm_source=atom_feed" rel="related" type="text/html" title="The Scientific Python Development Guide" />
                <link href="https://blog.scientific-python.org/numpy/fellowship-program/?utm_source=atom_feed" rel="related" type="text/html" title="NumPy&#39;s first Developer in Residence: Sayed Adel" />
                <link href="https://blog.scientific-python.org/numpy/mukulikapahari/?utm_source=atom_feed" rel="related" type="text/html" title="NumPy Contributor Spotlight: Mukulika Pahari" />
                <link href="https://blog.scientific-python.org/matplotlib/how-to-create-custom-tables/?utm_source=atom_feed" rel="related" type="text/html" title="How to create custom tables" />
                <link href="https://blog.scientific-python.org/matplotlib/visualising-usage-using-batteries/?utm_source=atom_feed" rel="related" type="text/html" title="Battery Charts - Visualise usage rates &amp; more" />
            
                <id>https://blog.scientific-python.org/numpy/numpy-rng/</id>
            
            
            <published>2024-01-26T23:22:46+02:00</published>
            <updated>2024-01-26T23:22:46+02:00</updated>
            
            
            <content type="html"><![CDATA[<blockquote>Best Practices for Using NumPy&rsquo;s Random Number Generators</blockquote><p>Given the practical challenges of achieving true randomness, deterministic algorithms, known as Pseudo Random Number Generators (RNGs), are employed in science to create sequences that mimic randomness. These generators are used for simulations, experiments, and analysis where it is essential to have numbers that appear unpredictable. I want to share here what I have learned about best practices with pseudo RNGs and especially the ones available in <a href="https://numpy.org/">NumPy</a>.</p>
<p>A pseudo RNG works by updating an internal state through a deterministic algorithm. This internal state is initialized with a value known as a seed and each update produces a number that appears randomly generated. The key here is that the process is deterministic, meaning that if you start with the same seed and apply the same algorithm, you will get the same sequence of internal states (and numbers). Despite this determinism, the resulting numbers exhibit properties of randomness, appearing unpredictable and evenly distributed. Users can either specify the seed manually, providing a degree of control over the generated sequence, or they can opt to let the RNG object automatically derive the seed from system entropy. The latter approach enhances unpredictability by incorporating external factors into the seed.</p>
<p>I assume a certain knowledge of NumPy and that NumPy 1.17 or greater is used. The reason for this is that great new features were introduced in the <a href="https://numpy.org/doc/stable/reference/random/index.html">random</a> module of version 1.17. As <code>numpy</code> is usually imported as <code>np</code>, I will sometimes use <code>np</code> instead of <code>numpy</code>. Finally, RNG will always mean pseudo RNG in the rest of this blog post.</p>
<h3 id="the-main-messages">The main messages<a class="headerlink" href="#the-main-messages" title="Link to this heading">#</a></h3>
<ol>
<li>Avoid using the global NumPy RNG. This means that you should avoid using <a href="https://numpy.org/doc/stable/reference/random/generated/numpy.random.seed.html"><code>np.random.seed</code></a> and <code>np.random.*</code> functions, such as <code>np.random.random</code>, to generate random values.</li>
<li>Create a new RNG and pass it around using the <a href="https://numpy.org/doc/stable/reference/random/generator.html#numpy.random.default_rng"><code>np.random.default_rng</code></a> function.</li>
<li>Be careful with parallel random number generation and use the <a href="https://numpy.org/doc/stable/reference/random/parallel.html">strategies provided by NumPy</a>.</li>
</ol>
<p>Note that, with older versions of NumPy (&lt;1.17), the way to create a new RNG is to use <a href="https://numpy.org/doc/stable/reference/random/legacy.html#numpy.random.RandomState"><code>np.random.RandomState</code></a> which is based on the popular Mersenne Twister 19937 algorithm. This is also how the global NumPy RNG is created. This function is still available in newer versions of NumPy, but it is now recommended to use <code>default_rng</code> instead, which returns an instance of the statistically better <a href="https://www.pcg-random.org">PCG64</a> RNG. You might still see <code>np.random.RandomState</code> being used in tests as it has strong stability guarantees between different NumPy versions.</p>
<h2 id="random-number-generation-with-numpy">Random number generation with NumPy<a class="headerlink" href="#random-number-generation-with-numpy" title="Link to this heading">#</a></h2>
<p>When you import <code>numpy</code> in your Python script, an RNG is created behind the scenes. This RNG is the one used when you generate a new random value using a function such as <code>np.random.random</code>. I will here refer to this RNG as the global NumPy RNG.</p>
<p>Although not recommended, it is a common practice to reset the seed of this global RNG at the beginning of a script using the <code>np.random.seed</code> function. Fixing the seed at the beginning ensures that the script is reproducible: the same values and results will be produced each time you run it. However, although sometimes convenient, using the global NumPy RNG is a bad practice. A simple reason is that using global variables can lead to undesired side effects. For instance one might use <code>np.random.random</code> without knowing that the seed of the global RNG was set somewhere else in the codebase. Quoting <a href="https://numpy.org/neps/nep-0019-rng-policy.html">Numpy Enhancement Proposal (NEP) 19</a> by Robert Kern:</p>
<blockquote>
<p>The implicit global RandomState behind the <code>np.random.*</code> convenience functions can cause problems, especially when threads or other forms of concurrency are involved. Global state is always problematic. We categorically recommend avoiding using the convenience functions when reproducibility is involved. [&hellip;] The preferred best practice for getting reproducible pseudorandom numbers is to instantiate a generator object with a seed and pass it around.</p>
</blockquote>
<p>In short:</p>
<ul>
<li>Instead of using <code>np.random.seed</code>, which reseeds the already created global NumPy RNG, and then using <code>np.random.*</code> functions, you should create a new RNG.</li>
<li>You should create an RNG at the beginning of your script (with your own seed if you want reproducibility) and use this RNG in the rest of the script.</li>
</ul>
<p>To create a new RNG you can use the <code>default_rng</code> function as illustrated in the <a href="https://numpy.org/doc/stable/reference/random/index.html">introduction of the random module documentation</a>:</p>


<div class="highlight">
  <pre class="chroma"><code><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">rng</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">default_rng</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="n">rng</span><span class="o">.</span><span class="n">random</span><span class="p">()</span>  <span class="c1"># generate a floating point number between 0 and 1</span></span></span></code></pre>
</div>
<p>If you want to use a seed for reproducibility, <a href="https://numpy.org/doc/stable/reference/random/index.html#quick-start">the NumPy documentation</a> recommends using a large random number, where large means at least 128 bits. The first reason for using a large random number is that this increases the probability of having a different seed than anyone else and thus independent results. The second reason is that relying only on small numbers for your seeds can lead to biases as they do not fully explore the state space of the RNG. This limitation implies that the first number generated by your RNG may not seem as random as expected due to inaccessible first internal states. For example, some numbers will never be produced as the first output. One possibility would be to pick the seed at random in the state space of the RNG but <a href="https://github.com/numpy/numpy/issues/25778#issuecomment-1930441151">according to Robert Kern</a> a 128-bit random number is large enough<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>. To generate a 128-bit random number for your seed you can rely on the <a href="https://docs.python.org/3/library/secrets.html">secrets module</a>:</p>


<div class="highlight">
  <pre class="chroma"><code><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">secrets</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">secrets</span><span class="o">.</span><span class="n">randbits</span><span class="p">(</span><span class="mi">128</span><span class="p">)</span></span></span></code></pre>
</div>
<p>When running this code I get <code>65647437836358831880808032086803839626</code> for the number to use as my seed. This number is randomly generated so you need to copy paste the value that is returned by <code>secrets.randbits(128)</code> otherwise you will have a different seed each time you run your code and thus break reproducibility:</p>


<div class="highlight">
  <pre class="chroma"><code><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">seed</span> <span class="o">=</span> <span class="mi">65647437836358831880808032086803839626</span>
</span></span><span class="line"><span class="cl"><span class="n">rng</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">default_rng</span><span class="p">(</span><span class="n">seed</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">rng</span><span class="o">.</span><span class="n">random</span><span class="p">()</span></span></span></code></pre>
</div>
<p>The reason for seeding your RNG only once (and passing that RNG around) is that with a good RNG such as the one returned by <code>default_rng</code> you will be ensured good randomness and independence of the generated numbers. However, if not done properly, using several RNGs (each one created with its own seed) might lead to streams of random numbers that are less independent than the ones created from the same seed<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup>. That being said, <a href="https://github.com/numpy/numpy/issues/15322#issuecomment-573890207">as explained by Robert Kern</a>, with the RNGs and seeding strategies introduced in NumPy 1.17, it is considered fairly safe to create RNGs using system entropy, i.e. using <code>default_rng(None)</code> multiple times. However as explained later be careful when running jobs in parallel and relying on <code>default_rng(None)</code>. Another reason for seeding your RNG only once is that obtaining a good seed can be time consuming. Once you have a good seed to instantiate your generator, you might as well use it.</p>
<h2 id="passing-a-numpy-rng-around">Passing a NumPy RNG around<a class="headerlink" href="#passing-a-numpy-rng-around" title="Link to this heading">#</a></h2>
<p>As you write functions that you will use on their own as well as in a more complex script it is convenient to be able to pass a seed or your already created RNG. The function <code>default_rng</code> allows you to do this very easily. As written above, this function can be used to create a new RNG from your chosen seed, if you pass a seed to it, or from system entropy when passing <code>None</code> but you can also pass an already created RNG. In this case the returned RNG is the one that you passed.</p>


<div class="highlight">
  <pre class="chroma"><code><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">stochastic_function</span><span class="p">(</span><span class="n">high</span><span class="o">=</span><span class="mi">10</span><span class="p">,</span> <span class="n">rng</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="n">rng</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">default_rng</span><span class="p">(</span><span class="n">rng</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">rng</span><span class="o">.</span><span class="n">integers</span><span class="p">(</span><span class="n">high</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span></span></span></code></pre>
</div>
<p>You can either pass an <code>int</code> seed or your already created RNG to <code>stochastic_function</code>. To be perfectly exact, the <code>default_rng</code> function returns the exact same RNG passed to it for certain kind of RNGs such at the ones created with <code>default_rng</code> itself. You can refer to the <a href="https://numpy.org/doc/stable/reference/random/generator.html#numpy.random.default_rng"><code>default_rng</code> documentation</a> for more details on the arguments that you can pass to this function<sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup>.</p>
<h2 id="parallel-processing">Parallel processing<a class="headerlink" href="#parallel-processing" title="Link to this heading">#</a></h2>
<p>You must be careful when using RNGs in conjunction with parallel processing. Let&rsquo;s consider the context of Monte Carlo simulation: you have a random function returning random outputs and you want to generate these random outputs a lot of times, for instance to compute an empirical mean. If the function is expensive to compute, an easy solution to speed up the computation time is to resort to parallel processing. Depending on the parallel processing library or backend that you use different behaviors can be observed. For instance if you do not set the seed yourself it can be the case that forked Python processes use the same random seed, generated for instance from system entropy, and thus produce the exact same outputs which is a waste of computational resources. A very nice example illustrating this when using the Joblib parallel processing library is available <a href="https://joblib.readthedocs.io/en/latest/auto_examples/parallel_random_state.html">here</a>.</p>
<p>If you fix the seed at the beginning of your main script for reproducibility and then pass your seeded RNG to each process to be run in parallel, most of the time this will not give you what you want as this RNG will be deep copied. The same results will thus be produced by each process. One of the solutions is to create as many RNGs as parallel processes with a different seed for each of these RNGs. The issue now is that you cannot choose the seeds as easily as you would think. When you choose two different seeds to instantiate two different RNGs how do you know that the numbers produced by these RNGs will appear as statistically independent?<sup id="fnref1:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup> The design of independent RNGs for parallel processes has been an important research question. See, for example, <a href="https://www.sciencedirect.com/science/article/pii/S0378475416300829">Random numbers for parallel computers: Requirements and methods, with emphasis on GPUs</a> by L&rsquo;Ecuyer et al. (2017) for a good summary of different methods.</p>
<p>Starting with NumPy 1.17, it is now very easy to instantiate independent RNGs. Depending on the type of RNG you use, different strategies are available as documented in the <a href="https://numpy.org/doc/stable/reference/random/parallel.html">Parallel random number generation section</a> of the NumPy documentation. One of the strategies is to use <code>SeedSequence</code> which is an algorithm that makes sure that poor input seeds are transformed into good initial RNG states. More precisely, this ensures that you will not have a degenerate behavior from your RNG and that the subsequent numbers will appear random and independent. Additionally, it ensures that close seeds are mapped to very different initial states, resulting in RNGs that are, with very high probability, independent of each other. You can refer to the documentation of <a href="https://numpy.org/doc/stable/reference/random/parallel.html#seedsequence-spawning">SeedSequence Spawning</a> for examples on how to generate independent RNGs from a <code>SeedSequence</code> or an existing RNG. I here show how to apply this to the <a href="https://joblib.readthedocs.io/en/latest/auto_examples/parallel_random_state.html#fixing-the-random-state-to-obtain-deterministic-results">joblib example</a> mentioned above.</p>


<div class="highlight">
  <pre class="chroma"><code><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">joblib</span> <span class="kn">import</span> <span class="n">Parallel</span><span class="p">,</span> <span class="n">delayed</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">stochastic_function</span><span class="p">(</span><span class="n">high</span><span class="o">=</span><span class="mi">10</span><span class="p">,</span> <span class="n">rng</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="n">rng</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">default_rng</span><span class="p">(</span><span class="n">rng</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">rng</span><span class="o">.</span><span class="n">integers</span><span class="p">(</span><span class="n">high</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">seed</span> <span class="o">=</span> <span class="mi">319929794527176038403653493598663843656</span>
</span></span><span class="line"><span class="cl"><span class="c1"># creating the RNG that is passed around.</span>
</span></span><span class="line"><span class="cl"><span class="n">rng</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">default_rng</span><span class="p">(</span><span class="n">seed</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1"># create 5 independent RNGs</span>
</span></span><span class="line"><span class="cl"><span class="n">child_rngs</span> <span class="o">=</span> <span class="n">rng</span><span class="o">.</span><span class="n">spawn</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># use 2 processes to run the stochastic_function 5 times with joblib</span>
</span></span><span class="line"><span class="cl"><span class="n">random_vector</span> <span class="o">=</span> <span class="n">Parallel</span><span class="p">(</span><span class="n">n_jobs</span><span class="o">=</span><span class="mi">2</span><span class="p">)(</span>
</span></span><span class="line"><span class="cl">    <span class="n">delayed</span><span class="p">(</span><span class="n">stochastic_function</span><span class="p">)(</span><span class="n">rng</span><span class="o">=</span><span class="n">child_rng</span><span class="p">)</span> <span class="k">for</span> <span class="n">child_rng</span> <span class="ow">in</span> <span class="n">child_rngs</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">random_vector</span><span class="p">)</span></span></span></code></pre>
</div>
<p>By using a fixed seed you always get the same results each time you run this code and by using <code>rng.spawn</code> you have an independent RNG for each call to <code>stochastic_function</code>. Note that here you could also spawn from a <code>SeedSequence</code> that you would create with the seed instead of creating an RNG. However, in general you pass around an RNG therefore I only assume to have access to an RNG. Also note that spawning from an RNG is only possible from version 1.25 of NumPy<sup id="fnref:4"><a href="#fn:4" class="footnote-ref" role="doc-noteref">4</a></sup>.</p>
<p>I hope this blog post helped you understand the best ways to use NumPy RNGs. The new Numpy API gives you all the tools you need for that. The resources below are available for further reading. Finally, I would like to thank Pamphile Roy, Stefan van der Walt and Jarrod Millman for their great feedbacks and comments which contributed to greatly improve the original version of this blog post.</p>
<h2 id="resources">Resources<a class="headerlink" href="#resources" title="Link to this heading">#</a></h2>
<h3 id="numpy-rngs">Numpy RNGs<a class="headerlink" href="#numpy-rngs" title="Link to this heading">#</a></h3>
<ul>
<li><a href="https://numpy.org/doc/stable/reference/random/index.html">The documentation of the NumPy random module</a> is the best place to find information and where I found most of the information that I share here.</li>
<li><a href="https://numpy.org/neps/nep-0019-rng-policy.html">The Numpy Enhancement Proposal (NEP) 19 on the Random Number Generator Policy</a> which lead to the changes introduced in NumPy 1.17</li>
<li>A <a href="https://github.com/numpy/numpy/issues/15322">NumPy issue</a> about the <code>check_random_state</code> function and RNG good practices, especially <a href="https://github.com/numpy/numpy/issues/15322#issuecomment-573890207">this comment</a> by Robert Kern.</li>
<li>Check also <a href="https://github.com/numpy/numpy/issues/25778#issuecomment-1930441151">this answer of Robert Kern</a> to my question about what <code>SeedSequence</code> can and cannot do. This also explains why it is recommended to use very large random numbers for seeds.</li>
<li><a href="https://scikit-learn.org/stable/faq.html#how-do-i-set-a-random-state-for-an-entire-execution">How do I set a random_state for an entire execution?</a> from the scikit-learn FAQ.</li>
<li>There are <a href="https://github.com/scientific-python/specs/pull/180">ongoing discussions</a> about uniformizing the APIs used by different libraries to seed RNGs.</li>
</ul>
<h3 id="rngs-in-general">RNGs in general<a class="headerlink" href="#rngs-in-general" title="Link to this heading">#</a></h3>
<ul>
<li><a href="https://www.sciencedirect.com/science/article/pii/S0378475416300829">Random numbers for parallel computers: Requirements and methods, with emphasis on GPUs</a> by L&rsquo;Ecuyer et al. (2017)</li>
<li>To know more about the default RNG used in NumPy, named PCG, I recommend the <a href="https://www.pcg-random.org/paper.html">PCG paper</a> which also contains lots of useful information about RNGs in general. The <a href="https://www.pcg-random.org">pcg-random.org website</a> is also full of interesting information about RNGs.</li>
</ul>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>If you only need a seed for reproducibility and do not need independence with respect to others, say for a unit test, a small seed is perfectly fine.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>A good RNG is expected to produce independent numbers for a given seed. However, the independence of sequences generated from two different seeds is not always guaranteed. For instance, it is possible that the sequence started with the second seed might quickly converge to an internal state also obtained by the first seed. This can result in both RNGs producing the same subsequent numbers, which would compromise the randomness expected from distinct seeds.&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a>&#160;<a href="#fnref1:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:3">
<p>Before knowing about <code>default_rng</code>, and before NumPy 1.17, I was using the scikit-learn function <a href="https://scikit-learn.org/stable/modules/generated/sklearn.utils.check_random_state.html"><code>check_random_state</code></a> which is of course heavily used in the scikit-learn codebase. While writing this post I discovered that this function is now available in <a href="https://github.com/scipy/scipy/blob/62d2af2e13280d29781585aa39a3c5a5dfdfba17/scipy/_lib/_util.py#L231">scipy</a>. A look at the docstring and/or the source code of this function will give you a good idea about what it does. The differences with <code>default_rng</code> are that <code>check_random_state</code> currently relies on <code>np.random.RandomState</code> and that when <code>None</code> is passed to <code>check_random_state</code> then the function returns the already existing global NumPy RNG. The latter can be convenient because if you fix the seed of the global RNG before in your script using <code>np.random.seed</code>, <code>check_random_state</code> returns the generator that you seeded. However, as explained above, this is not the recommended practice and you should be aware of the risks and the side effects.&#160;<a href="#fnref:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:4">
<p>Before 1.25 you need to get the <code>SeedSequence</code> from the RNG using the <code>_seed_seq</code> private attribute of the underlying bit generator: <code>rng.bit_generator._seed_seq</code>. You can then spawn from this <code>SeedSequence</code> to get child seeds that will result in independent RNGs.&#160;<a href="#fnref:4" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>]]></content>
            
                 
                    
                 
                    
                         
                        
                            
                             
                                <category scheme="taxonomy:Tags" term="tutorials" label="tutorials" />
                             
                                <category scheme="taxonomy:Tags" term="numpy" label="numpy" />
                             
                                <category scheme="taxonomy:Tags" term="rng" label="rng" />
                            
                        
                    
                
            
        </entry>
    
</feed>
