Последовательно создайте один и тот же случайный массив

Я жду, пока другой разработчик завершит работу над кодом, который вернет массив np формы (100,2000) со значениями -1,0 или 1.

В то же время я хочу случайным образом создать массив с такими же характеристиками, чтобы я мог получить преимущество в своей разработке и тестировании. Дело в том, что я хочу, чтобы этот случайно созданный массив был одинаковым каждый раз, чтобы я не проверял массив, который постоянно меняет свое значение при каждом повторном запуске моего процесса.

Я могу создать свой массив таким образом, но есть ли способ создать его так, чтобы он каждый раз был одинаковым. Я могу мариновать объект и раскрывать его, но не знаю, есть ли другой способ.

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

6 ответов

Решение

Просто запустите генератор случайных чисел с фиксированным значением, например

numpy.random.seed(42)

Таким образом, вы всегда получите одну и ту же последовательность случайных чисел.

Создайте свой собственный экземпляр 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])

Я просто хочу кое-что прояснить в отношении ответа @Robert Kern на случай, если это неясно. Даже если вы используетеRandomState вам придется инициализировать его каждый раз, когда вы вызываете случайный метод 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])

Основываясь на последних обновлениях случайной выборки , предпочтительным способом является использование генераторов вместо RandomState . См , чтобы сравнить оба подхода. Одним из ключевых изменений является отличие медленного генератора псевдослучайных чисел Mersenne Twister () от потока случайных битов на основе разных алгоритмов ( BitGenerators), используемый в новом подходе ( Generators).

В противном случае шаги для создания случайного массива numpy очень похожи:

  1. Инициализировать генератор случайных чисел

Вместо RandomStateвы инициализируете генератор случайных чисел. default_rngрекомендуемый конструктор для генератора случайных чисел, но вы можете попробовать и другие способы.

      import numpy as np

rng = np.random.default_rng(42)
# rng -> Generator(PCG64)
  1. Создать пустой массив

Вместо randintметод, есть метод Generator.integers , который теперь является каноническим способом генерации целочисленных случайных чисел из дискретного равномерного распределения (см. уже упомянутое . Что нового или отличается«Что нового или другое резюме»). Обратите внимание, что endpoint=Trueиспользует [низкий, высокий] интервал для выборки вместо значения по умолчанию [низкий, высокий].

      arr = rng.integers(-1, 1, size=10, endpoint=True)
# array([-1,  1,  0,  0,  0,  1, -1,  1, -1, -1])

Как уже говорилось, вам нужно каждый раз инициализировать генератор случайных чисел (или случайное состояние), чтобы сгенерировать идентичный массив. Поэтому самое простое — определить пользовательскую функцию, аналогичную той, что была в ответе @mari756h:

      def get_array(low, high, size, random_state=42, endpoint=True):
    rng = np.random.default_rng(random_state)
    return rng.integers(low, high, size=size, endpoint=endpoint)

Когда вы вызываете функцию с одними и теми же параметрами, вы всегда получаете идентичный массив numpy.

      get_array(-1, 1, 10)
# array([-1,  1,  0,  0,  0,  1, -1,  1, -1, -1])

get_array(-1, 1, 10, random_state=12345)  # change random state to get different array
# array([ 1, -1,  1, -1, -1,  1,  0,  1,  1,  0])

get_array(-1, 1, (2, 2), endpoint=False)
# array([[-1,  0],
#        [ 0, -1]])

И для ваших нужд вы бы использовали get_array(-1, 1, size=(100, 2000)).

Если вы используете другие функции, полагающиеся на случайное состояние, вы не можете просто установить и общее начальное значение, но вместо этого следует создать функцию для генерации случайного списка чисел и установить начальное значение в качестве параметра функции. Это не будет мешать другим случайным генераторам в коде:

# 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)

Важно понять, что является семенем генератора случайных чисел и когда / как он установлен в вашем коде (см., Например, здесь для хорошего объяснения математического значения семени).

Для этого вам нужно установить начальное значение, выполнив:

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

Тогда важно генерировать случайные числа из random_state, а не из np.random. Т.е. вы должны сделать:

random_state.randint(...)

вместо

np.random.randint(...) 

который создаст новый экземпляр RandomState() и в основном использует внутренние часы вашего компьютера для установки начального числа.

Другие вопросы по тегам