title: Why is numpy.random.seed() a legacy function?
body: <p>I often use <code>numpy.random.seed()</code> for reproducibility of results. I also find it helpful when books/tutorials use it (e.g., <code>np.random.seed(42)</code>), so that people can reproduce things more easily.</p>
  <p>The <a href="https://numpy.org/doc/stable/reference/random/generated/numpy.random.seed.html" rel="nofollow noreferrer">the documentation</a> for <code>random.seed()</code> now says it is not encouraged and is a legacy function, but without any explanation. I am wondering why:</p>
  <pre><code>random.seed()
  
  Reseed a legacy MT19937 BitGenerator
  
  This is a convenience, legacy function.
  
  The best practice is to not reseed a BitGenerator, 
  rather to recreate a new one. This method is here 
  for legacy reasons.
  </code></pre>
  <h3>More details</h3>
  <p>Note the documentation goes on to say:</p>
  <pre><code># This example demonstrates best practice.
  from numpy.random import MT19937
  from numpy.random import RandomState, SeedSequence
  rs = RandomState(MT19937(SeedSequence(123456789)))
  # Later, you want to restart the stream
  rs = RandomState(MT19937(SeedSequence(987654321)))
  </code></pre>
  <p>I'm not sure why this is best practice. Why is that better than using <code>random.seed()</code>? In particular, when you are teaching a concept and want to reproduce the same result every time and want to keep your code simple? At least on the surface, <code>random.seed()</code> also invokes the <code>MT19937</code> BitGenerator (though from the docs it is a <em>legacy</em> bit generator, so they are not the same).</p>