random — Generate pseudo-random numbers

Вихідний код: Lib/random.py


Цей модуль реалізує генератори псевдовипадкових чисел для різних розподілів.

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

На реальній лінії існують функції для обчислення рівномірного, нормального (гауссового), логарифмічного нормального, від’ємного експоненціального, гамма- та бета-розподілу. Для генерації розподілу кутів доступний розподіл фон Мізеса.

Almost all module functions depend on the basic function random(), which generates a random float uniformly in the semi-open range [0.0, 1.0). Python uses the Mersenne Twister as the core generator. It produces 53-bit precision floats and has a period of 2**19937-1. The underlying implementation in C is both fast and threadsafe. The Mersenne Twister is one of the most extensively tested random number generators in existence. However, being completely deterministic, it is not suitable for all purposes, and is completely unsuitable for cryptographic purposes.

Функції, які надає цей модуль, насправді є зв’язаними методами прихованого екземпляра класу random.Random. Ви можете створити власні екземпляри Random, щоб отримати генератори, які не мають спільного стану.

Class Random can also be subclassed if you want to use a different basic generator of your own devising: in that case, override the random(), seed(), getstate(), and setstate() methods. Optionally, a new generator can supply a getrandbits() method — this allows randrange() to produce selections over an arbitrarily large range.

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

Попередження

Псевдовипадкові генератори цього модуля не слід використовувати з метою безпеки. Щоб отримати відомості про безпеку чи криптографію, перегляньте модуль secrets.

Дивись також

M. Matsumoto and T. Nishimura, «Mersenne Twister: 623-dimensionally equidistributed uniform pseudorandom number generator», ACM Transactions on Modeling and Computer Simulation Vol. 8, № 1, січень 3-30 1998.

Complementary-Multiply-with-Carry recipe for a compatible alternative random number generator with a long period and comparatively simple update operations.

Бухгалтерські функції

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)

Returns a Python integer with k random bits. This method is supplied with the Mersenne Twister generator and some other generators may also provide it as an optional part of the API. When available, getrandbits() enables randrange() to handle arbitrarily large ranges.

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

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

Return a randomly selected element from range(start, stop, step). This is equivalent to choice(range(start, stop, step)), but doesn’t actually build a range object.

The positional argument pattern matches that of range(). Keyword arguments should not be used because the function may use them in unexpected ways.

Змінено в версії 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, вибраних із популяції із заміною. Якщо популяція порожня, викликає IndexError.

Якщо вказано послідовність ваг, вибір робиться відповідно до відносних ваг. Крім того, якщо вказано послідовність cum_weights, вибір робиться відповідно до кумулятивних ваг (можливо, обчислених за допомогою itertools.accumulate()). Наприклад, відносні ваги [10, 5, 30, 5] еквівалентні кумулятивним вагам [10, 15, 45, 50]. Внутрішньо відносні ваги перетворюються на кумулятивні ваги перед вибором, тому надання кумулятивних ваг економить роботу.

Якщо ані weights, ані cum_weights не вказано, вибір робиться з рівною ймовірністю. Якщо надається послідовність ваг, вона має бути такої ж довжини, що й послідовність населеності. Це TypeError, якщо вказати weights і cum_weights.

The weights or cum_weights can use any numeric type that interoperates with the float values returned by random() (that includes integers, floats, and fractions but excludes decimals). Weights are assumed to be non-negative.

For a given seed, the choices() function with equal weighting typically produces a different sequence than repeated calls to choice(). The algorithm used by choices() uses floating point arithmetic for internal consistency and speed. The algorithm used by choice() defaults to integer arithmetic with repeated selections to avoid small biases from round-off error.

Нове в версії 3.6.

random.shuffle(x[, random])

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

The optional argument random is a 0-argument function returning a random float in [0.0, 1.0); by default, this is the function random().

Щоб перетасувати незмінну послідовність і повернути новий перетасований список, замість цього використовуйте sample(x, k=len(x)).

Зауважте, що навіть для невеликого len(x) загальна кількість перестановок x може швидко зрости більше, ніж період більшості генераторів випадкових чисел. Це означає, що більшість перестановок довгої послідовності ніколи не можуть бути згенеровані. Наприклад, послідовність довжиною 2080 є найбільшою, яка може поміститися в період генератора випадкових чисел Мерсенна Твістера.

random.sample(population, k)

Return a k length list of unique elements chosen from the population sequence or set. Used for random sampling without replacement.

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

Члени сукупності не повинні бути hashable або унікальними. Якщо популяція містить повтори, то кожен випадок є можливим вибором у вибірці.

Щоб вибрати вибірку з діапазону цілих чисел, використовуйте об’єкт range() як аргумент. Це особливо швидко та ефективно для вибірки з великої сукупності: sample(range(10000000), k=60).

Якщо розмір вибірки більший за розмір сукупності, виникає помилка ValueError.

Дійсні розподіли

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

random.random()

Return the next random floating point number in the range [0.0, 1.0).

random.uniform(a, b)

Return a random floating point number N such that a <= N <= b for a <= b and b <= N <= a for b < a.

The end-point value b may or may not be included in the range depending on floating-point rounding in the equation a + (b-a) * random().

random.triangular(low, high, mode)

Return a random floating point number N such that low <= N <= high and with the specified mode between those bounds. The low and high bounds default to zero and one. The mode argument defaults to the midpoint between the bounds, giving a symmetric distribution.

random.betavariate(alpha, beta)

Бета-розповсюдження. Умови параметрів: альфа > 0 і бета > 0. Діапазон повернених значень від 0 до 1.

random.expovariate(lambd)

Експоненціальний розподіл. lambd дорівнює 1,0, поділеному на бажане середнє. Воно повинно бути відмінним від нуля. (Параметр мав би назву «лямбда», але це зарезервоване слово в Python.) Повернені значення варіюються від 0 до нескінченності, якщо lambd додатне, і від нескінченності до 0, якщо lambd є від’ємним.

random.gammavariate(alpha, beta)

Gamma distribution. (Not the gamma function!) Conditions on the parameters are alpha > 0 and beta > 0.

Функція розподілу ймовірностей:

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

Gaussian distribution. mu is the mean, and sigma is the standard deviation. This is slightly faster than the normalvariate() function defined below.

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)

Розподіл Парето. альфа — це параметр форми.

random.weibullvariate(alpha, beta)

Розподіл Вейбулла. альфа — параметр масштабу, а бета — параметр форми.

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

class random.Random([seed])

Клас, який реалізує генератор псевдовипадкових чисел за замовчуванням, який використовується модулем random.

class random.SystemRandom([seed])

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

Примітки щодо відтворюваності

Sometimes it is useful to be able to reproduce the sequences given by a pseudo random number generator. By re-using a seed value, the same sequence should be reproducible from run to run as long as multiple threads are not running.

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

  • Якщо додано новий метод посіву, буде запропоновано зворотно сумісний сівалка.

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

Examples and Recipes

Основні приклади:

>>> random()                             # Random float:  0.0 <= x < 1.0
0.37444887175646646

>>> uniform(2.5, 10.0)                   # Random float:  2.5 <= x < 10.0
3.1800146073117523

>>> expovariate(1 / 5)                   # Interval between arrivals averaging 5 seconds
5.148957571865031

>>> randrange(10)                        # Integer from 0 to 9 inclusive
7

>>> randrange(0, 101, 2)                 # Even integer from 0 to 100 inclusive
26

>>> choice(['win', 'lose', 'draw'])      # Single random element from a sequence
'draw'

>>> deck = 'ace two three four'.split()
>>> shuffle(deck)                        # Shuffle a list
>>> deck
['four', 'two', 'ace', 'three']

>>> sample([10, 20, 30, 40, 50], k=4)    # Four samples without replacement
[40, 10, 50, 30]

Симуляції:

>>> # Six roulette wheel spins (weighted sampling with replacement)
>>> choices(['red', 'black', 'green'], [18, 18, 2], k=6)
['red', 'green', 'black', 'black', 'red', 'black']

>>> # Deal 20 cards without replacement from a deck of 52 playing cards
>>> # and determine the proportion of cards with a ten-value
>>> # (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

>>> # Estimate the probability of getting 5 or more heads from 7 spins
>>> # of a biased coin that settles on heads 60% of the time.
>>> 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  # time when each server becomes available
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}.')

Дивись також

Statistics for Hackers відеоурок від Jake Vanderplas зі статистичного аналізу з використанням лише кількох фундаментальних концепцій, включаючи моделювання, вибірку, перетасування та перехресну перевірку.

Economics Simulation a simulation of a marketplace by Peter Norvig that shows effective use of many of the tools and distributions provided by this module (gauss, uniform, sample, betavariate, choice, triangular, and randrange).

A Concrete Introduction to Probability (using Python) a tutorial by Peter Norvig covering the basics of probability theory, how to write simulations, and how to perform data analysis using Python.