Послідовно створюйте той самий випадковий масив Numpy


89

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

Тим часом, я хочу випадковим чином створити масив з однаковими характеристиками, щоб я міг створити фору для розробки та тестування. Річ у тім, що я хочу, щоб цей випадково створений масив кожного разу був однаковим, щоб я не тестував масив, який постійно змінює своє значення кожного разу, коли я повторно запускаю свій процес.

Я можу створити свій масив таким чином, але чи є спосіб створити його таким чином, щоб він кожного разу був однаковим. Я можу замаринувати предмет і зняти його, але цікаво, чи є інший спосіб.

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

Відповіді:


84

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

numpy.random.seed(42)

Таким чином, ви завжди отримаєте однакову послідовність випадкових чисел.


43
Хтось підкрався до numpy.random.seed()функції, коли я не звертав уваги. :-) Я навмисно залишив це поза оригінальним модулем. Я рекомендую людям використовувати власні екземпляри RandomStateта передавати ці предмети навколо.
— Роберт Керн,

6
Роберт є основним фактором, який сприяє numpy. Я думаю, що ми повинні надати його думці певну вагу.
— застаріле

10
@deprecated: Я вдячний за роботу Роберта, але його робота не може замінити аргументування рекомендацій. Крім того, якщо використання numpy.random.seed()не рекомендується, про це слід зазначити в документації . Очевидно, інші автори NumPy не поділяють думки Роберта. Жоден образи не призначений, мені просто цікаво.
— Sven Marnach

13
Це те саме, що використання random.seedпроти використання random.Randomоб’єкта у стандартній бібліотеці Python. Якщо ви використовуєте random.seedабо numpy.random.seed, ви засіваєте всі випадкові екземпляри як у своєму коді, так і в коді, який ви викликаєте, або коді, який запускається в тому ж сеансі, що і ваш. Якщо ці речі залежать від того, що насправді є випадковими, тоді у вас починають виникати проблеми. Якщо ви розгорнете код, який встановлює випадкове насіння, ви можете ввести вразливість системи безпеки.
— asmeurer

3
@asmeurer Той, хто використовує генератор псевдовипадкових чисел для цілей безпеки, ймовірно, не знає, що вони роблять.
— JAB

191

Створіть свій власний екземпляр 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])

7
Чи є у вас обґрунтування для вашої рекомендації? В чому проблема numpy.random.seed()? Я знаю, що це не захищено від ниток, але це справді зручно, якщо вам не потрібна захист від потоків.
— Sven Marnach

52
В основному це формування хороших звичок. Можливо, вам зараз не потрібні незалежні потоки, але Sven-6-місяців відтепер можуть. Якщо ви пишете свої бібліотеки для використання методів безпосередньо з numpy.random, ви не зможете робити незалежні потоки пізніше. Також простіше писати бібліотеки з наміром контролювати потоки PRNG. Завжди існує декілька способів увійти у вашу бібліотеку, і кожен із них повинен мати спосіб контролю насіння. Переміщення об'єктів PRNG - це більш чистий спосіб зробити це, ніж покладатися numpy.random.seed(). На жаль, це поле для коментарів занадто коротке, щоб містити більше прикладів. :-)
— Роберт Керн,

25
Інший спосіб описати обгрунтування Роберта: використання numpy.random.seed використовує глобальну змінну для збереження стану PRNG, і тут застосовуються ті самі стандартні причини, що глобальні змінні є поганими.
— Робі Басак

9
Якщо ви хочете, щоб PRNG були незалежними, не засівайте їх нічим. Просто використовуйте numpy.random.RandomState()без аргументів. Це призведе до стану унікальних значень, отриманих із засобів вашої операційної системи для таких речей ( /dev/urandomна машинах UNIX та еквівалентах Windows). Якщо numpy.random.RandomState(1234567890)у вас не працює, будь ласка, покажіть, що саме ви ввели, і саме повідомлення про помилку, яке ви отримали.
— Роберт Керн

5
Не гарна ідея. Використовуйте numpy.random.RandomState()без аргументів для найкращих результатів.
— Роберт Керн,

3

Якщо ви використовуєте інші функції, які покладаються на випадковий стан, ви не можете просто встановити і загальний насіння, а натомість слід створити функцію для генерації вашого випадкового списку чисел і встановити насіння як параметр функції. Це не заважатиме будь-яким іншим генераторам випадкових випадків у коді:

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

3

Важливо зрозуміти, що таке насіння випадкового генератора і коли / як воно встановлене у вашому коді (перевірте, наприклад, тут гарне пояснення математичного значення насіння).

Для цього вам потрібно встановити насіння, виконавши:

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

Тоді важливо генерувати випадкові числа з random_state, а не з np.random. Тобто ви повинні зробити:

random_state.randint(...)

замість

np.random.randint(...) 

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


2

Я просто хочу пояснити щось щодо відповіді @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])
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.