Відмінності між numpy.random та random.random в Python


100

У мене великий сценарій у Python. Я надихнув себе кодом інших людей, тому я в кінцевому підсумку використовував numpy.randomмодуль для деяких речей (наприклад, для створення масиву випадкових чисел, взятих з біноміального розподілу), а в інших місцях використовую модуль random.random.

Може хтось, будь ласка, скажіть мені основні відмінності між ними? Переглядаючи веб-сторінку doc для кожної з двох, мені здається, що numpy.randomпросто є більше методів, але мені незрозуміло, чим відрізняється генерація випадкових чисел.

Причина, чому я прошу, полягає в тому, що мені потрібно викласти свою основну програму для налагодження. Але це не працює, якщо я не використовую однаковий генератор випадкових чисел у всіх модулях, які я імпортую, чи правильно це?

Також я прочитав тут, в іншому дописі, дискусію про НЕ використання numpy.random.seed(), але я не дуже зрозумів, чому це така погана ідея. Я був би дуже вдячний, якщо хтось пояснить мені, чому це так.

Відповіді:


120

Ви вже зробили багато правильних спостережень!

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

Бо numpy.random.seed()головна складність полягає в тому, що він не є безпечним для потоків - тобто його не безпечно використовувати, якщо у вас є багато різних потоків виконання , оскільки це не гарантується, якщо функція виконує дві різні нитки одночасно. Якщо ви не використовуєте теми, і якщо ви обґрунтовано очікуєте, що вам не потрібно буде переписувати програму таким чином у майбутньому, numpy.random.seed()має бути добре. Якщо є якісь причини підозрювати, що вам можуть знадобитися нитки в майбутньому, набагато безпечніше в перспективі зробити так, як пропонується, і зробити локальний екземпляр numpy.random.Randomкласу . Наскільки я можу сказати, він random.random.seed()є безпечним для потоків (або, принаймні, я не знайшов жодних доказів протилежного).

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

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

В якості примітки, якщо ви дійсно потрібні криптографічний рівня хаотичності, ви повинні використовувати секрети модуль або що - щось на зразок Crypto.Random , якщо ви використовуєте версію Python раніше , ніж Python 3.6.


14
Як віддалену пов’язану примітку, іноді не потрібно використовувати жодне , оскільки твістер Мерсен не створює випадкових послідовностей ентропії, достатніх для криптографічних (і деяких незвичних наукових) цілей. У тих рідкісних випадках вам часто потрібен Crypto.Random , який здатний використовувати специфічні для ОС джерела ентропії для генерування недетермінованих випадкових послідовностей набагато вищої якості, ніж це доступно в random.randomсамоті. Однак зазвичай це вам не потрібно.
SingleNegationElimination

Дякую, Hannnele Ваша думка була дійсно дуже корисною! Виявляється, я не можу уникнути, використовуючи ТІЛЬКИ один генератор випадкових чисел ((який повинен бути numpy, оскільки random не виробляє біноміального розподілу), оскільки частини моєї програми викликають іншу програму, яка використовує random. Мені доведеться посіяти два генератори.
Лаура

2
"якщо ви знаєте, яке число у вас зараз, можна з абсолютною впевненістю передбачити, яке число буде наступним." Я думаю, це твердження може потребувати певного роз'яснення. Мається на увазі те, що якщо ви знаєте внутрішній стан генератора, ви можете відтворити послідовність - що саме ви робите, коли ви засіваєте генератор. Враховуючи вихід одного генератора з генератора, не можна передбачити наступне число. Період настільки великий, що, ймовірно, знадобиться довга послідовність чисел, перш ніж ви зможете обчислити, де ви знаходитесь на псевдовипадковій послідовності, і таким чином передбачити наступний.
Kaushik Ghose

12

З Python для аналізу даних , модуль numpy.randomдоповнює Python randomфункціями для ефективного генерування цілих масивів вибіркових значень з багатьох видів розподілу ймовірностей.

На відміну від цього, вбудований randomмодуль Python вибіркує лише одне значення за раз, тоді як numpy.randomможе швидше генерувати дуже великий зразок. За допомогою магічної функції IPython %timeitможна побачити, який модуль працює швидше:

In [1]: from random import normalvariate
In [2]: N = 1000000

In [3]: %timeit samples = [normalvariate(0, 1) for _ in xrange(N)]
1 loop, best of 3: 963 ms per loop

In [4]: %timeit np.random.normal(size=N)
10 loops, best of 3: 38.5 ms per loop

1
Це не стосується інших методів. порівняно np.random.randint(2)з random.randrange(2)та NumPy був повільнішим . NumPy: 1,25 us та Random: 891 нс. А також те саме відношення для np.random.rand()і random.random().
Шаян Амані

3

Джерело насіннєвого матеріалу та використовуваний профіль розподілу впливатимуть на результати - якщо ви шукаєте криптографічної випадковості, висівання з os.urandom () отримає майже реальні випадкові байти з балачки пристроїв (тобто мережевої мережі або диска) (тобто / розробник / випадковий на BSD)

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

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


Щиро дякую Поле, ваша відповідь була справді корисною! Я не шукаю криптографічних випадковостей, я займаюся математичним моделюванням і псевдовипадкових чисел мені достатньо. Виявляється, я не можу приєднатися до одного генератора, як хотілося, оскільки мені потрібен numpy для біноміального розподілу, і моя програма викликає іншу програму, яка використовує випадкові випадки :(
Laura
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.