Послідовно створюйте той самий випадковий масив 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.