random
— Gera números pseudoaleatórios¶
Código-fonte: Lib/random.py
Este módulo implementa geradores de números pseudoaleatórios para várias distribuições.
Para números inteiros, há uma seleção uniforme de um intervalo. Para sequências, há uma seleção uniforme de um elemento aleatório, uma função para gerar uma permutação aleatória de uma lista internamanete e uma função para amostragem aleatória sem substituição.
Na linha real, existem funções para calcular distribuições uniforme, normal (gaussiana), log-normal, exponencial negativa, gama e beta. Para gerar distribuições de ângulos, a distribuição de von Mises está disponível.
Quase todas as funções do módulo dependem da função básica random()
, que gera um ponto flutuante aleatório uniformemente no intervalo semiaberto [0.0, 1.0). Python usa o Mersenne Twister como gerador de núcleo. Produz pontos flutuantes de precisão de 53 bits e possui um período de 2**19937-1. A implementação subjacente em C é rápida e segura para threads. O Mersenne Twister é um dos geradores de números aleatórios mais amplamente testados existentes. No entanto, sendo completamente determinístico, não é adequado para todos os fins e é totalmente inadequado para fins criptográficos.
As funções fornecidas por este módulo são, na verdade, métodos vinculados de uma instância oculta da classe random.Random
. Você pode instanciar suas próprias instâncias de Random
para obter geradores que não compartilham estado.
A classe Random
também pode ser usado como subclasse se você quiser usar um gerador básico diferente de sua preferência: nesse caso, substitua os métodos random()
, seed()
, getstate()
e setstate()
. Opcionalmente, um novo gerador pode fornecer um método getrandbits()
— isso permite que randrange()
produza seleções a um intervalo grande arbitrário.
O módulo random
também fornece a classe SystemRandom
que usa a função do sistema os.urandom()
para gerar números aleatórios a partir de fontes fornecidas pelo sistema operacional.
Aviso
Os geradores pseudoaleatórios deste módulo não devem ser usados para fins de segurança. Para segurança ou uso criptográfico, veja o módulo secrets
.
Ver também
M. Matsumoto and T. Nishimura, “Mersenne Twister: A 623-dimensionally equidistributed uniform pseudorandom number generator”, ACM Transactions on Modeling and Computer Simulation Vol. 8, No. 1, January pp.3–30 1998.
Receita de Complementary-Multiply-with-Carry para um gerador de números aleatórios alternativo compatível com um longo período e operações de atualização comparativamente simples.
Funções de contabilidade¶
-
random.
seed
(a=None, version=2)¶ Inicializa o gerador de números aleatórios.
Se a for omitido ou
None
, a hora atual do sistema será usada. Se fontes de aleatoriedade são fornecidas pelo sistema operacional, elas são usadas no lugar da hora do sistema (consulte a funçãoos.urandom()
para detalhes sobre disponibilidade).Se a é um int, ele é usado diretamente.
Com a versão 2 (o padrão), o objeto a
str
,bytes
oubytearray
é convertido em um objetoint
e todos os seus bits são usados.Com a versão 1 (fornecida para reproduzir sequências aleatórias de versões mais antigas do Python), o algoritmo para
str
ebytes
gera um intervalo mais restrito de sementes.Alterado na versão 3.2: Movido para o esquema da versão 2, que usa todos os bits em uma semente de strings.
-
random.
getstate
()¶ Retorna um objeto capturando o estado interno atual do gerador. Este objeto pode ser passado para
setstate()
para restaurar o estado.
-
random.
setstate
(state)¶ state deveria ter sido obtido de uma chamada anterior para
getstate()
, esetstate()
restaura o estado interno do gerador para o que era no momento quegetstate()
foi chamado.
-
random.
getrandbits
(k)¶ Retorna um número inteiro Python com bits aleatórios k. Este método é fornecido com o gerador Mersenne Twister e alguns outros geradores também podem fornecê-lo como uma parte opcional da API. Quando disponível,
getrandbits()
permite querandrange()
manipular intervalos arbitrariamente grandes.
Funções para inteiros¶
-
random.
randrange
(stop)¶ -
random.
randrange
(start, stop[, step]) Retorna um elemento selecionado aleatoriamente em
range(start, stop, step)
. Isso é equivalente achoice(range(start, stop, step))
, mas na verdade não cria um objeto range.O padrão de argumento posicional corresponde ao de
range()
. Os argumentos nomeados não devem ser usados porque a função pode usá-los de maneiras inesperadas.Alterado na versão 3.2:
randrange()
é mais sofisticado em produzir valores igualmente distribuídos. Anteriormente, usava um estilo comoint(random()*n)
, que poderia produzir distribuições ligeiramente desiguais.
-
random.
randint
(a, b)¶ Retorna um inteiro aleatório N de forma que
a <= N <= b
. Apelido pararandrange(a, b+1)
.
Funções para sequências¶
-
random.
choice
(seq)¶ Retorna um elemento aleatório da sequência não vazia seq. Se seq estiver vazio, levanta
IndexError
.
-
random.
choices
(population, weights=None, *, cum_weights=None, k=1)¶ Retorna uma lista do tamanho de k de elementos escolhidos da population com substituição. Se a population estiver vazio, levanta
IndexError
.Se uma sequência weights for especificada, as seleções serão feitas de acordo com os pesos relativos. Alternativamente, se uma sequência cum_weights for fornecida, as seleções serão feitas de acordo com os pesos cumulativos (talvez calculados usando
itertools.accumulate()
). Por exemplo, os pesos relativos[10, 5, 30, 5]
são equivalentes aos pesos cumulativos[10, 15, 45, 50]
. Internamente, os pesos relativos são convertidos em pesos acumulados antes de fazer seleções, portanto, fornecer pesos cumulativos economiza trabalho.Se nem weights nem cum_weights forem especificados, as seleções serão feitas com igual probabilidade. Se uma sequência de pesos for fornecida, ela deverá ter o mesmo comprimento que a sequência population. É um
TypeError
para especificar ambos os weights e cum_weights.O weights ou o cum_weights podem usar qualquer tipo numérico que interopera com os valores
float
retornados porrandom()
(que inclui números inteiros, flutuadores e frações, mas exclui decimais). Os pesos são assumidos como não negativos.Para uma dada semente, a função
choices()
com igual peso normalmente produz uma sequência diferente das chamadas repetidas parachoice()
. O algoritmo usado porchoice()
usa aritmética de ponto flutuante para consistência e velocidade internas. O algoritmo usado porchoice()
assume como padrão aritmética inteira com seleções repetidas para evitar pequenos vieses de erro de arredondamento.Novo na versão 3.6.
-
random.
shuffle
(x[, random])¶ Embaralha a sequência x internamente.
O argumento opcional random é uma função de 0 argumentos retornando um ponto flutuante aleatório em [0.0, 1.0); por padrão, esta é a função
random()
.Para embaralhar uma sequência imutável e retornar uma nova lista embaralhada, use
sample(x, k=len(x))
.Observe que, mesmo para pequenos
len(x)
, o número total de permutações de x pode crescer rapidamente maior que o período da maioria dos geradores de números aleatórios. Isso implica que a maioria das permutações de uma longa sequência nunca pode ser gerada. Por exemplo, uma sequência de comprimento 2080 é a maior que pode caber no período do gerador de números aleatórios Mersenne Twister.
-
random.
sample
(population, k)¶ Retorna uma lista de comprimento k de elementos exclusivos escolhidos a partir da sequência ou conjunto da população. Usado para amostragem aleatória sem substituição.
Retorna uma nova lista contendo elementos da população, mantendo a população original inalterada. A lista resultante está na ordem de seleção, para que todas as subfatias também sejam amostras aleatórias válidas. Isso permite que os vencedores do sorteio (a amostra) sejam divididos em grandes prêmios e vencedores de segundo lugar (as subfatias).
Os membros da população não precisam ser hasheáveis ou únicos. Se a população contiver repetições, cada ocorrência é uma seleção possível na amostra.
Para escolher uma amostra de um intervalo de números inteiros, use um objeto
range()
como argumento. Isso é especialmente rápido e com eficiência de espaço para amostragem de uma grande população:sample(range(10000000), k=60)
.Se o tamanho da amostra for maior que o tamanho da população, uma
ValueError
é levantada.
Distribuições com valor real¶
As funções a seguir geram distribuições específicas com valor real. Os parâmetros de função são nomeados após as variáveis correspondentes na equação da distribuição, conforme usadas na prática matemática comum; a maioria dessas equações pode ser encontrada em qualquer texto estatístico.
-
random.
random
()¶ Retorna o próximo número de ponto flutuante aleatório no intervalo [0.0, 1.0).
-
random.
uniform
(a, b)¶ Retorna um número de ponto flutuante aleatório N de forma que
a <= N <= b
paraa <= b
eb <= N <= a
parab < a
.O valor do ponto final
b
pode ou não ser incluído no intervalo, dependendo do arredondamento do ponto flutuante na equaçãoa + (b-a) * random()
.
-
random.
triangular
(low, high, mode)¶ Retorna um número de ponto flutuante aleatório N de forma que
low <= N <= high
e com o mode especificado entre esses limites. Os limites low e high são padronizados como zero e um. O argumento mode assume como padrão o ponto médio entre os limites, fornecendo uma distribuição simétrica.
-
random.
betavariate
(alpha, beta)¶ Distribuição beta. As condições nos parâmetros são
alpha > 0
ebeta > 0
. Os valores retornados variam entre 0 e 1.
-
random.
expovariate
(lambd)¶ Distribuição exponencial. lambd é 1.0 dividido pela média desejada. Deve ser diferente de zero. (O parâmetro seria chamado “lambda”, mas é uma palavra reservada em Python.) Os valores retornados variam de 0 a infinito positivo se lambd for positivo e de infinito negativo a 0 se lambd for negativo.
-
random.
gammavariate
(alpha, beta)¶ Distribuição gama. (Não a função gama!) As condições nos parâmetros são
alpha > 0
ebeta > 0
.A função de distribuição de probabilidade é:
x ** (alpha - 1) * math.exp(-x / beta) pdf(x) = -------------------------------------- math.gamma(alpha) * beta ** alpha
-
random.
gauss
(mu, sigma)¶ Distribuição gaussiana. mu é a média e sigma é o desvio padrão. Isso é um pouco mais rápido que a função
normalvariate()
definida abaixo.
-
random.
lognormvariate
(mu, sigma)¶ Distribuição log normal. Se você usar o logaritmo natural dessa distribuição, obterá uma distribuição normal com média mu e desvio padrão sigma. mu pode ter qualquer valor e sigma deve ser maior que zero.
-
random.
normalvariate
(mu, sigma)¶ Distribuição normal. mu é a média e sigma é o desvio padrão.
-
random.
vonmisesvariate
(mu, kappa)¶ mu é o ângulo médio, expresso em radianos entre 0 e 2*pi, e kappa é o parâmetro de concentração, que deve ser maior ou igual a zero. Se kappa for igual a zero, essa distribuição será reduzida para um ângulo aleatório uniforme no intervalo de 0 a 2*pi.
-
random.
paretovariate
(alpha)¶ Distribuição de Pareto. alpha é o parâmetro de forma.
-
random.
weibullvariate
(alpha, beta)¶ Distribuição Weibull. alpha é o parâmetro de escala e beta é o parâmetro de forma.
Gerador alternativo¶
-
class
random.
Random
([seed])¶ Classe que implementa o gerador de números pseudoaleatórios padrão usado pelo módulo
random
.
-
class
random.
SystemRandom
([seed])¶ Classe que usa a função
os.urandom()
para gerar números aleatórios a partir de fontes fornecidas pelo sistema operacional. Não disponível em todos os sistemas. Não depende do estado do software e as sequências não são reproduzíveis. Assim, o métodoseed()
não tem efeito e é ignorado. Os métodosgetstate()
esetstate()
levantamNotImplementedError
se chamados.
Notas sobre reprodutibilidade¶
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.
A maioria dos algoritmos e funções de propagação do módulo aleatório está sujeita a alterações nas versões de Python, mas dois aspectos são garantidos para não serem alterados:
Se um novo método de semeadura for adicionado, será oferecida um semeador compatível com versões anteriores.
O método
random()
do gerador continuará produzindo a mesma sequência quando o semeador compatível receber a mesma semente.
Exemplos e receitas¶
Exemplos básicos:
>>> 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]
Simulações:
>>> # 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
Exemplo de bootstrapping estatístico usando reamostragem com substituição para estimar um intervalo de confiança para a média de uma amostra:
# 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}')
Exemplo de um teste de permutação de reamostragem para determinar a significância estatística ou valor-p de uma diferença observada entre os efeitos de uma droga em comparação com um placebo:
# 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.')
Simulação de tempos de chegada e entregas de serviços para uma fila multisservidor:
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}.')
Ver também
Statistics for Hackers um tutorial em vídeo por Jake Vanderplas sobre análise estatística usando apenas alguns conceitos fundamentais, incluindo simulação, amostragem, embaralhamento e validação cruzada.
Economics Simulation uma simulação de um mercado por Peter Norvig isso mostra o uso eficaz de muitas das ferramentas e distribuições fornecidas por este módulo (gauss, uniforme, amostra, betavariado, escolha, triangular e intervalo).
A Concrete Introduction to Probability (using Python) um tutoria por Peter Norvig cobrindo o básico da teoria das probabilidades, como escrever simulações e como realizar análise de dados usando Python.