Различия между numpy.random и random.random в Python - PullRequest
83 голосов
/ 11 августа 2011

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

Может кто-нибудь сказать мне основные различия между ними? Глядя на веб-страницу документа по каждому из двух, мне кажется, что numpy.random просто имеет больше методов, но мне неясно, чем отличается генерация случайных чисел.

Причина, по которой я спрашиваю, заключается в том, что мне нужно заполнить основную программу для целей отладки. Но это не сработает, если я не использую один и тот же генератор случайных чисел во всех импортируемых модулях, это правильно?

Кроме того, я прочитал здесь, в другом посте, обсуждение НЕ использовать numpy.random.seed(), но я не совсем понял, почему это была такая плохая идея. Я был бы очень признателен, если бы кто-нибудь объяснил мне, почему это так.

Ответы [ 3 ]

101 голосов
/ 11 августа 2011

Вы уже сделали много правильных наблюдений!

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

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

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

В противном случае они оба используют последовательность Мерсена твистера , чтобы генерировать их случайные числа, и они оба полностью детерминированы - то есть, если вы знаете несколько ключевых битов информации, можно с абсолютной уверенностью предсказать , какое число будет дальше .По этой причине ни numpy.random, ни random.random не подходят для любых серьезных криптографических применений .Но поскольку последовательность очень и очень длинная, оба подходят для генерации случайных чисел в тех случаях, когда вы не беспокоитесь о людях, пытающихся перепроектировать ваши данные.Это также является причиной необходимости заполнения случайного значения - если вы начинаете каждый раз в одном и том же месте, вы всегда получите одну и ту же последовательность случайных чисел!

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

9 голосов
/ 08 мая 2017

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

В отличие от этого, встроенный в Python модуль random производит выборку только одного значения за раз, тогда как 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
3 голосов
/ 11 августа 2011

Источник начального числа и используемый профиль распределения будут влиять на выходные данные - если вы ищете криптографическую случайность, при заполнении из os.urandom () будут получены почти реальные случайные байты из болтовни устройства (например, ethernet или диск)(т. е. / dev / random в BSD)

это позволит вам не давать начальное число и, следовательно, генерировать детерминированные случайные числа.Однако случайные вызовы затем позволяют вам подогнать числа к распределению (то, что я называю научной случайностью - в конечном итоге все, что вам нужно - это распределение случайных чисел по кривой колокольчика, лучше всего справиться с numpy)., придерживайтесь одного генератора, но решите, какой случайный вы хотите - случайный, но не зависимо от кривой искажения, или настолько случайный, насколько вы можете получить без квантового устройства.

...