Why do I get different random numbers with the same seed?

129 views Asked by At

I am using the numpy random number generator with the following MWE:

import numpy as np
np.random.seed(40)
print(np.random.randint(-3, 4))
rng = np.random.default_rng(seed=40)
print(rng.integers(-3, 4))

This outputs:

3
0

Why are the outputs different?

2

There are 2 answers

0
user2357112 On BEST ANSWER

numpy.random.randint and numpy.random.seed use the old random API, with an entirely different implementation under the hood. numpy.random.default_rng creates a Generator object, which is the new API.

The two APIs are effectively two entirely separate RNG libraries that happen to live in the same namespace. Output isn't expected to match, even with the same seed.

2
duburcqa On

Actually, numpy provides still access to legacy generators through np.random.RandomState. The latter can be use to get exactly the same result using the new object-oriented random API than the old global state based API. Its documentation can be found here:

import numpy as np
np.random.seed(40)

print(np.random.randint(-3, 4))

rng = np.random.RandomState(40)
print(rng.randint(-3, 4))

However, it does not expose exactly the same user API as the new Generator class, and no compatibility layer between the old and the new API is provided.

Another, more hacky option, is to initialize Generator with the same generator as the one used by the old global state under the hood:

import numpy as np
np.random.seed(40)

print(np.random.rand(4))

mt19937 = np.random.MT19937()
np.random.seed(40)
mt19937.state = np.random.rand.__self__.get_state()
rng = np.random.Generator(mt19937)
print(rng.random(4))

Then, it will give you the same result in most cases, but there is no guarantee for that ! Typically, np.random.rand is the same as rng.random, but np.random.randint is different from rng.integers because the internal sampling algorithm is different.