Gerar matriz aleatória de flutuadores entre um intervalo


88

Não consegui encontrar uma função para gerar uma matriz de flutuadores aleatórios de um determinado comprimento entre um determinado intervalo.

Eu olhei para Amostragem aleatória, mas nenhuma função parece fazer o que eu preciso.

random.uniform chega perto, mas retorna apenas um único elemento, não um número específico.

Isso é o que eu procuro:

ran_floats = some_function(low=0.5, high=13.3, size=50)

que retornaria uma matriz de 50 flutuadores aleatórios não exclusivos (isto é: repetições são permitidas) uniformemente distribuídas no intervalo [0.5, 13.3].

Existe tal função?


5
Você marcou a pergunta numpy, mas não a mencionou numpy.random.uniform, embora ela tenha exatamente a assinatura de chamada desejada. Você tem a numpybiblioteca disponível?
DSM de

1
[random.uniform(low, high) for i in xrange(size)]
Filogênese

1
@DSM sim, e você está aparentemente 100% correto. Perdi essa função e parece fazer exatamente o que preciso. Você se importaria de apresentar seu comentário como uma resposta?
Gabriel

Respostas:


135

np.random.uniform se encaixa no seu caso de uso:

sampl = np.random.uniform(low=0.5, high=13.3, size=(50,))

Atualização em outubro de 2019:

Embora a sintaxe ainda seja compatível, parece que a API mudou com o NumPy 1.17 para oferecer suporte a maior controle sobre o gerador de números aleatórios. Daqui para frente, a API mudou e você deve olhar em https://docs.scipy.org/doc/numpy/reference/random/generated/numpy.random.Generator.uniform.html

A proposta de aprimoramento está aqui: https://numpy.org/neps/nep-0019-rng-policy.html


23
A pergunta de pesquisa intuitiva do OP é some_function(low=0.5, high=13.3, size=50). É assim que as libs python são projetadas #wow
Saravanabalagi Ramachandran

O tamanho não estava totalmente claro e o link não funciona. Aqui está um pequeno esclarecimento. size: int ou tupla de ints, opcional. Forma de saída. Se a forma fornecida for, por exemplo, (m, n, k), então m * n * k amostras são retiradas. Se o tamanho for nenhum padrão), um único valor será retornado se baixo e alto forem ambos escalares.
vlad

@vlad - obrigado por apontar o problema com o link. Eu atualizei a resposta para cobrir o uso atual.
JoshAdel

20

Por que não usar uma compreensão de lista?

Em Python 2

ran_floats = [random.uniform(low,high) for _ in xrange(size)]

Em Python 3, rangefunciona como xrange( ref )

ran_floats = [random.uniform(low,high) for _ in range(size)]

3

Por que não combinar random.uniform com uma compreensão de lista?

>>> def random_floats(low, high, size):
...    return [random.uniform(low, high) for _ in xrange(size)]
... 
>>> random_floats(0.5, 2.8, 5)
[2.366910411506704, 1.878800401620107, 1.0145196974227986, 2.332600336488709, 1.945869474662082]

3

Pode já haver uma função para fazer o que você está procurando, mas eu não sei (ainda?). Nesse ínterim, sugiro usar:

ran_floats = numpy.random.rand(50) * (13.3-0.5) + 0.5

Isso produzirá uma matriz de forma (50,) com uma distribuição uniforme entre 0,5 e 13,3.

Você também pode definir uma função:

def random_uniform_range(shape=[1,],low=0,high=1):
    """
    Random uniform range

    Produces a random uniform distribution of specified shape, with arbitrary max and
    min values. Default shape is [1], and default range is [0,1].
    """
    return numpy.random.rand(shape) * (high - min) + min

EDIT : Hmm, sim, então eu perdi, há numpy.random.uniform () com a mesma chamada exata que você deseja! Tente import numpy; help(numpy.random.uniform)obter mais informações.


3

O loop for na compreensão da lista leva tempo e o torna lento. É melhor usar parâmetros numpy (baixo, alto, tamanho, ..etc)

import numpy as np
import time
rang = 10000
tic = time.time()
for i in range(rang):
    sampl = np.random.uniform(low=0, high=2, size=(182))
print("it took: ", time.time() - tic)

tic = time.time()
for i in range(rang):
    ran_floats = [np.random.uniform(0,2) for _ in range(182)]
print("it took: ", time.time() - tic)

saída de amostra:

('levou:', 0,06406784057617188)

('levou:', 1,7253198623657227)


3

Alternativamente, você pode usar SciPy

from scipy import stats
stats.uniform(0.5, 13.3).rvs(50)

e para o registro de amostras inteiras é

stats.randint(10, 20).rvs(50)

2

Esta é a maneira mais simples

np.random.uniform(start,stop,(rows,columns))

0

np.random.random_sample(size) irá gerar flutuações aleatórias no intervalo semiaberto [0,0, 1,0).

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.