random — Генерация псевдослучайных чисел

Исходный код: Lib/random.py


Модуль реализует генераторы псевдослучайных чисел для различных распределений.

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

На реальной линии есть функции для вычисления равномерного, нормального (гауссова), логнормальное, отрицательное экспоненциальное, гамма и бета распределение. Для генерации углового распределения, доступно распределение Мизеса.

Почти все функции модуля зависят от базовой функции random(), которая генерирует случайную float равномерно в полуоткрытом диапазоне [0,0, 1,0). Python использует Mersenne Twister в качестве основного генератора. Он производит 53-разрядные прецизионные поплавки и имеет период 2**19937-1. Базовая реализация в C является как быстрой, так и многопоточной. Мерсеннский твистер является одним из наиболее тщательно протестированных генераторов случайных чисел в настоящее время. Однако будучи полностью детерминированным, он подходит не для всех целей, и совершенно непригоден для криптографических целей.

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

Класс Random может также быть подклассифицирован, если вы хотите использовать другой основной генератор своего собственного изобретения: в этом случае отвергните random(), seed(), getstate() и методы setstate(). Произвольно, новый генератор может поставлять метод getrandbits() —, это позволяет randrange() производить выборы по произвольно большому спектру.

Модуль random также предоставляет класс SystemRandom, который использует системную функцию os.urandom() для генерации случайных чисел из источников, предоставляемых операционной системой.

Предупреждение

Псевдослучайные генераторы этого модуля не должны быть используемый в целях безопасности. Сведения о безопасности или использовании шифрования см. в разделе модуля secrets.

См.также

M. Matsumoto и T. Nishimura, «Mersenne Twister: A 623-мерно равнораспределенное однородное псевдослучайное число генератор,» ACM Transactions on Modeling and Computer Simulation Vol. 8, No. 1, January pp.3 - 30 1998.

Рецепт дополнительного умножения с переносом для совместимого альтернативного случайного числа генератор с длительным периодом и сравнительно простыми операциями обновления.

Бухгалтерские функции

random.seed(a=None, version=2)

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

Если a пропущен или None, текущее системное время равно используемый. Если источники случайности предоставляются операционной системой, они являются используемый вместо системного времени (подробнее о доступности см. функцию os.urandom()).

Если a является int, то это используемый напрямую.

В версии 2 (по умолчанию) объект str, bytes или bytearray преобразуется в int, и все его биты являются используемый.

В версии 1 (предусмотренной для воспроизведения случайных последовательностей из более старых версий Python) алгоритм для str и bytes генерирует более узкий диапазон начальных чисел.

Изменено в версии 3.2: Перемещен в схему версии 2, в которой используются все биты начального числа строка.

random.getstate()

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

random.setstate(state)

state должен был быть получен от предыдущего требования до getstate(), и setstate() восстанавливает внутренний состояние генератор к тому, чем это было в то время, когда getstate() назвали.

random.getrandbits(k)

Возвращает целое число Python со случайными битами k. Этот метод поставляет Twister Mersenne генератор и некоторые другие генераторы могут также обеспечить ему как дополнительной части API. Когда доступно, getrandbits() включает randrange() обращаться с произвольно большими спектрами.

Функции для целых чисел

random.randrange(stop)
random.randrange(start, stop[, step])

Возвращает случайно выбранный элемент из range(start, stop, step). Это эквивалентно choice(range(start, stop, step)), но фактически не создает объект диапазона.

Шаблон позиционных аргументов соответствует шаблону range(). Аргументы ключевых слов не должны быть используемый, поскольку функция может использовать их неожиданными способами.

Изменено в версии 3.2: randrange() более сложен в производстве равномерно распределенных значения. Раньше это используемый стиль как int(random()*n), который мог произвести немного неравномерные распределения.

random.randint(a, b)

Возвращает случайный целочисленный N, таким образом, что a <= N <= b. Псевдоним для randrange(a, b+1).

Функции для последовательностей

random.choice(seq)

Возвращает случайный элемент из непустой последовательности seq. Если seq пуст, поднимает IndexError.

random.choices(population, weights=None, *, cum_weights=None, k=1)

Возвращает k измерил список элементов, выбранных из population с заменой. Если population пуст, поднимает IndexError.

Если указана последовательность weights, выбор выполняется в соответствии с относительными весами. Альтернативно, если задана последовательность cum_weights, то выбор производится в соответствии с кумулятивными весами (возможно, вычисленными с использованием itertools.accumulate()). Например, относительные веса [10, 5, 30, 5] эквивалентны совокупным весам [10, 15, 45, 50]. Внутри страны относительные веса перед выбором преобразуются в кумулятивные веса, что позволяет сохранить кумулятивные веса.

Если ни weights, ни cum_weights не указаны, то выбор производится с равной вероятностью. Если последовательность весов поставляется, это должна быть та же длина как последовательность population. Это TypeError для указания как weights, так и cum_weights.

В weights или cum_weights можно использовать любой числовой тип, взаимодействующий с float значения возвращенный по random() (включая целые числа, поплавки и доли, но исключая десятичные разряды). Предполагается, что веса неотрицательны.

Для данного начального числа функция choices() с равным весом обычно создает последовательность, отличную от повторяющихся вызовов для choice(). Алгоритм используемый by choices() использует арифметику с плавающей запятой для внутренней согласованности и скорости. Алгоритм используемый дефолтами choice() к целочисленной арифметике с повторными выборами, чтобы избежать маленьких уклонов от ошибки округления.

Добавлено в версии 3.6.

random.shuffle(x[, random])

Перемешать последовательность x на месте.

Необязательный аргумент random является 0-аргументной функцией, возвращающей случайное float в [0.0, 1.0); по умолчанию это функция random().

Чтобы перемешать неизменяемую последовательность и возвращает новый тасованный список, используйте команду sample(x, k=len(x)).

Заметим, что даже для малых len(x) общее число перестановок x может быстро расти больше, чем период большинства генераторов случайных чисел. Это означает, что большинство перестановок длинной последовательности никогда не может быть сгенерировано. Например, последовательность длины 2080 является самой большой, которая может вписываться в период случайного числа генератор мерсенна твистера.

random.sample(population, k)

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

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

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

Чтобы выбрать образец из диапазона целых чисел, используйте объект range() в качестве аргумента. Это особенно быстро и эффективно для отбора проб из большой популяции: sample(range(10000000), k=60).

Если объем выборки больше, чем размер популяции, поднимается ValueError.

Вещественные распределения

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

random.random()

Возвращает следующее случайное число с плавающей запятой в диапазоне [0,0, 1,0).

random.uniform(a, b)

Возвращает случайное число с плавающей запятой N такое, что a <= N <= b для a <= b и b <= N <= a для b < a.

значение b конечной точки может или не может быть включен в диапазон в зависимости от округления с плавающей запятой в уравнении a + (b-a) * random().

random.triangular(low, high, mode)

Возвращает случайное число с плавающей запятой N такое, что low <= N <= high и с указанным mode между этими границами. Значения low и high по умолчанию равны нулю и единице. Аргумент mode по умолчанию принимает середину между границами, давая симметричное распределение.

random.betavariate(alpha, beta)

Бета-распределение. Условия по параметрам - alpha > 0 и beta > 0. Возвращенные значения располагаются между 0 и 1.

random.expovariate(lambd)

Экспоненциальное распределение. lambd - 1,0 разделенных желаемым средним. Должно быть ненулевое. (Параметр будет называться «лямбда», но это зарезервированное слово в Python.) возвращенные значения колеблются от 0 до положительной бесконечности, если lambd положительный, и от отрицательной бесконечности до 0, если lambd отрицателен.

random.gammavariate(alpha, beta)

Гамма-распределение. (Not гамма-функция!) условия по параметрам - alpha > 0 и beta > 0.

Функция распределения вероятности имеет вид:

          x ** (alpha - 1) * math.exp(-x / beta)
pdf(x) =  --------------------------------------
            math.gamma(alpha) * beta ** alpha
random.gauss(mu, sigma)

Гауссово распределение. mu - среднее значение, а sigma - стандартное отклонение. Это немного быстрее, чем функция normalvariate(), определенная ниже.

random.lognormvariate(mu, sigma)

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

random.normalvariate(mu, sigma)

Нормальное распределение. mu - среднее значение, а sigma - стандартное отклонение.

random.vonmisesvariate(mu, kappa)

mu - средний угол, выраженный в радианах от 0 до 2*pi, а kappa - параметр концентрации, который должен быть больше или равен нулю. Если kappa равно нулю, это распределение уменьшается до равномерного случайного угла в диапазоне от 0 до 2*pi.

random.paretovariate(alpha)

Распределение Парето. alpha - параметр формы.

random.weibullvariate(alpha, beta)

Распределение Вейбулла. alpha - параметр масштаба, а beta - параметр формы.

Альтернативный генератор

class random.Random([seed])

Класс, реализующий псевдослучайное число генератор используемый по умолчанию модулем random.

class random.SystemRandom([seed])

Класс, использующий функцию os.urandom() для генерации случайных чисел из источников, предоставляемых операционной системой. Доступно не во всех системах. Не полагается на программное обеспечение состояние, и последовательности не воспроизводимы. Соответственно, метод seed() не имеет эффекта и игнорируется. Методы getstate() и setstate() поднимают NotImplementedError при вызове.

Примечания по воспроизводимости

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

Большинство алгоритмов и функций заполнения случайного модуля меняются в разных версиях Python, но два аспекта гарантированно не изменятся:

  • Если добавлен новый метод посева, то будет предложен обратно совместимый сеялка.
  • Способ random() генератор будет продолжать генерировать ту же последовательность, когда совместимому сеяльнику дают то же самое начальное число.

Примеры и рецепты

Основные примеры:

>>> random()                             # случайный float:  0.0 <= x < 1.0
0.37444887175646646

>>> uniform(2.5, 10.0)                   # случайный float:  2.5 <= x < 10.0
3.1800146073117523

>>> expovariate(1 / 5)                   # Интервал между прибытиями в среднем 5 секунд
5.148957571865031

>>> randrange(10)                        # Целое число от 0 до 9 включительно
7

>>> randrange(0, 101, 2)                 # Четное целое число от 0 до 100 включительно
26

>>> choice(['win', 'lose', 'draw'])      # Один случайный элемент из последовательности
'draw'

>>> deck = 'ace two three four'.split()
>>> shuffle(deck)                        # Перемешать список
>>> deck
['four', 'two', 'ace', 'three']

>>> sample([10, 20, 30, 40, 50], k=4)    # Четыре образца без замены
[40, 10, 50, 30]

Моделирования:

>>> # Шесть вращений колеса рулетки (взвешенная выборка с заменой)
>>> choices(['red', 'black', 'green'], [18, 18, 2], k=6)
['red', 'green', 'black', 'black', 'red', 'black']

>>> # Раздача 20 карт без замены из колоды из 52 игральных карт
>>> # и определить пропорцию карточек с 10 значением
>>> # (a ten, jack, queen, or king).
>>> deck = collections.Counter(tens=16, low_cards=36)
>>> seen = sample(list(deck.elements()), k=20)
>>> seen.count('tens') / 20
0.15

>>> # Оцените вероятность получения 5 или более "орлов" за 7 подбрасываний
>>> # смещенной монеты, которая оседает на "орлах" 60% времени.
>>> def trial():
...     return choices('HT', cum_weights=(0.60, 1.00), k=7).count('H') >= 5
...
>>> sum(trial() for i in range(10_000)) / 10_000
0.4169

>>> # Probability of the median of 5 samples being in middle two quartiles
>>> def trial():
...     return 2_500 <= sorted(choices(range(10_000), k=5))[2] < 7_500
...
>>> sum(trial() for i in range(10_000)) / 10_000
0.7958

Пример статистического бутстрапа с использованием повторной выборки с заменой для оценки доверительного интервала для среднего значения выборки:

# http://statistics.about.com/od/Applications/a/Example-Of-Bootstrapping.htm
from statistics import fmean as mean
from random import choices

data = [41, 50, 29, 37, 81, 30, 73, 63, 20, 35, 68, 22, 60, 31, 95]
means = sorted(mean(choices(data, k=len(data))) for i in range(100))
print(f'The sample mean of {mean(data):.1f} has a 90% confidence '
      f'interval from {means[5]:.1f} to {means[94]:.1f}')

Пример тест перестановки передискретизации для определения статистической значимости или p-значение наблюдаемой разницы между эффектами препарата и плацебо:

# Example from "Statistics is Easy" by Dennis Shasha and Manda Wilson
from statistics import fmean as mean
from random import shuffle

drug = [54, 73, 53, 70, 73, 68, 52, 65, 65]
placebo = [54, 51, 58, 44, 55, 52, 42, 47, 58, 46]
observed_diff = mean(drug) - mean(placebo)

n = 10_000
count = 0
combined = drug + placebo
for i in range(n):
    shuffle(combined)
    new_diff = mean(combined[:len(drug)]) - mean(combined[len(drug):])
    count += (new_diff >= observed_diff)

print(f'{n} label reshufflings produced only {count} instances with a difference')
print(f'at least as extreme as the observed difference of {observed_diff:.1f}.')
print(f'The one-sided p-value of {count / n:.4f} leads us to reject the null')
print(f'hypothesis that there is no difference between the drug and the placebo.')

Моделирование времени прибытия и поставок услуг для многосерверной очереди:

from heapq import heappush, heappop
from random import expovariate, gauss
from statistics import mean, median, stdev

average_arrival_interval = 5.6
average_service_time = 15.0
stdev_service_time = 3.5
num_servers = 3

waits = []
arrival_time = 0.0
servers = [0.0] * num_servers  # время, когда каждый сервер становится доступным
for i in range(100_000):
    arrival_time += expovariate(1.0 / average_arrival_interval)
    next_server_available = heappop(servers)
    wait = max(0.0, next_server_available - arrival_time)
    waits.append(wait)
    service_duration = gauss(average_service_time, stdev_service_time)
    service_completed = arrival_time + wait + service_duration
    heappush(servers, service_completed)

print(f'Mean wait: {mean(waits):.1f}.  Stdev wait: {stdev(waits):.1f}.')
print(f'Median wait: {median(waits):.1f}.  Max wait: {max(waits):.1f}.')

См.также

Статистика для хакеров видео обучающая программа Jake Vanderplas согласно статистическому анализу, используя всего несколько фундаментальных понятий включая моделирование, сэмплирование, перемешивание и перекрестную проверку.

Моделирование экономики моделирование рынка с помощью Peter Norvig, которое показывает эффективное использование многих инструментов и распределений, предоставляемых этим модулем (гаусс, равномерное, сэмплирование, бетавариант, перемешивание, треугольное и рандрандж).

Конкретное введение в теорию вероятностей (с использованием Python), учебник Peter Norvig, покрывающим основы теории вероятности, как написать моделирования, и как выполнить анализ данных, используя Python.