Genere una matriz aleatoria de flotadores entre un rango

88

No he podido encontrar una función para generar una matriz de flotadores aleatorios de una longitud determinada entre un rango determinado.

He examinado el muestreo aleatorio, pero ninguna función parece hacer lo que necesito.

random.uniform se acerca, pero solo devuelve un único elemento, no un número específico.

Esto es lo que busco:

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

que devolvería una matriz de 50 flotantes aleatorios no únicos (es decir, se permiten repeticiones) distribuidos uniformemente en el rango [0.5, 13.3].

¿Existe tal función?

Gabriel
fuente
5
Ha etiquetado la pregunta numpy, pero no la mencionó numpy.random.uniform, a pesar de que tiene exactamente la firma de llamada que desea. ¿Tiene la numpybiblioteca disponible?
DSM
1
[random.uniform(low, high) for i in xrange(size)]
Phylogenesis
1
@DSM sí, y aparentemente estás 100% correcto. Me perdí esa función y parece hacer exactamente lo que necesito. ¿Le importaría presentar su comentario como respuesta?
Gabriel

Respuestas:

135

np.random.uniform se adapta a su caso de uso:

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

Actualización de octubre de 2019:

Si bien la sintaxis aún es compatible, parece que la API cambió con NumPy 1.17 para admitir un mayor control sobre el generador de números aleatorios. En el futuro, la API ha cambiado y debería consultar https://docs.scipy.org/doc/numpy/reference/random/generated/numpy.random.Generator.uniform.html

La propuesta de mejora está aquí: https://numpy.org/neps/nep-0019-rng-policy.html

JoshAdel
fuente
23
La pregunta de búsqueda intuitiva de OP es some_function(low=0.5, high=13.3, size=50). Así de bien están diseñadas las bibliotecas de Python #wow
Saravanabalagi Ramachandran
El tamaño no estaba completamente claro y el enlace no funciona. Aquí hay una pequeña aclaración. tamaño: int o tupla de ints, opcional. Forma de salida. Si la forma dada es, por ejemplo, (m, n, k), entonces se extraen m * n * k muestras. Si el tamaño es Ninguno predeterminado), se devuelve un solo valor si tanto bajo como alto son escalares.
vlad
@vlad: gracias por señalar el problema con el enlace. Actualicé la respuesta para cubrir, con suerte, el uso actual.
JoshAdel
20

¿Por qué no utilizar una lista de comprensión?

En Python 2

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

En Python 3, rangefunciona como xrange( ref )

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

¿Por qué no combinar random.uniform con una lista de comprensión?

>>> 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]
pkacprzak
fuente
3

Puede que ya exista una función para hacer lo que estás buscando, pero no lo sé (¿todavía?). Mientras tanto, sugiero usar:

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

Esto producirá una matriz de forma (50,) con una distribución uniforme entre 0,5 y 13,3.

También puede definir una función:

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

EDITAR : Hmm, sí, así que me lo perdí, ¡hay numpy.random.uniform () con la misma llamada exacta que quieres! Intente import numpy; help(numpy.random.uniform)obtener más información.

PhilMacKay
fuente
3

El bucle for en la comprensión de la lista lleva tiempo y lo hace lento. Es mejor utilizar numerosos parámetros (bajo, alto, tamaño, ..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)

salida de muestra:

('tomó:', 0.06406784057617188)

('tomó:', 1.7253198623657227)

Mohamed Ibrahim
fuente
3

Alternativamente, puede usar SciPy

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

y para que el registro muestree enteros es

stats.randint(10, 20).rvs(50)
Stuart Hallows
fuente
2

Esta es la forma mas sencilla

np.random.uniform(start,stop,(rows,columns))
George Gee
fuente
0

np.random.random_sample(size) generará flotadores aleatorios en el intervalo semiabierto [0.0, 1.0).

shivaraj karki
fuente