una posiciones nĂºmeros numeros nombres matriz llenar lista generar datos con como aleatorios aleatorio aleatorias python random numpy scipy

posiciones - llenar una matriz con numeros aleatorios en python



Generando variables aleatorias discretas con pesos especificados usando SciPy o NumPy (5)

Estoy buscando una función simple que pueda generar una matriz de valores aleatorios específicos en función de sus probabilidades correspondientes (también especificadas). Solo necesito generar valores flotantes, pero no veo por qué no debería ser capaz de generar ningún escalar. Puedo pensar en muchas formas de construir esto a partir de las funciones existentes, pero creo que probablemente me perdí una función obvia de SciPy o NumPy.

P.ej:

>>> values = [1.1, 2.2, 3.3] >>> probabilities = [0.2, 0.5, 0.3] >>> print some_function(values, probabilities, size=10) (2.2, 1.1, 3.3, 3.3, 2.2, 2.2, 1.1, 2.2, 3.3, 2.2)

Nota: Encontré scipy.stats.rv_discrete pero no entiendo cómo funciona. Específicamente, no entiendo qué significa esto (abajo) ni qué debería hacer:

numargs = generic.numargs [ <shape(s)> ] = [''Replace with resonable value'', ]*numargs

Si rv_discrete es lo que debería estar usando, ¿podrían darme un ejemplo simple y una explicación de la declaración de "forma" anterior?


Aquí hay una función corta y relativamente simple que devuelve valores ponderados, usa NumPy''s random_sample , accumulate y random_sample .

import numpy as np from numpy.random import random_sample def weighted_values(values, probabilities, size): bins = np.add.accumulate(probabilities) return values[np.digitize(random_sample(size), bins)] values = np.array([1.1, 2.2, 3.3]) probabilities = np.array([0.2, 0.5, 0.3]) print weighted_values(values, probabilities, 10) #Sample output: [ 2.2 2.2 1.1 2.2 2.2 3.3 3.3 2.2 3.3 3.3]

Funciona así:

  1. Primero usando accumulate creamos contenedores.
  2. Luego creamos un grupo de números aleatorios (entre 0 y 1 ) usando la random_sample
  3. Usamos digitize para ver a qué contenedores pertenecen estos números.
  4. Y devuelve los valores correspondientes.

Dibujar desde una distribución discreta está directamente integrado en numpy. La función se llama random.choice (difícil de encontrar sin ninguna referencia a distribuciones discretas en los documentos numpy).

elements = [1.1, 2.2, 3.3] probabilities = [0.2, 0.5, 0.3] np.random.choice(elements, 10, p=probabilities)


La forma más sencilla de hacer el bricolaje sería resumir las probabilidades en una distribución acumulativa. De esta manera, divide el intervalo de la unidad en subintervalos de la longitud igual a sus probabilidades originales. Ahora genere un solo número aleatorio uniforme en [0,1), y vea a qué intervalo aterriza.


También podría usar Lea , un paquete de Python puro dedicado a distribuciones de probabilidad discretas.

>>> distrib = Lea.fromValFreqs((1.1,2),(2.2,5),(3.3,3)) >>> distrib 1.1 : 2/10 2.2 : 5/10 3.3 : 3/10 >>> distrib.random(10) (2.2, 2.2, 1.1, 2.2, 2.2, 2.2, 1.1, 3.3, 1.1, 3.3)

Et voilà!


scipy.stats.rv_discrete() en una buena dirección: el scipy.stats.rv_discrete() crea directamente una variable aleatoria discreta. Así es como funciona:

>>> from scipy.stats import rv_discrete >>> values = numpy.array([1.1, 2.2, 3.3]) >>> probabilities = [0.2, 0.5, 0.3] >>> distrib = rv_discrete(values=(range(len(values)), probabilities)) # This defines a Scipy probability distribution >>> distrib.rvs(size=10) # 10 samples from range(len(values)) array([1, 2, 0, 2, 2, 0, 2, 1, 0, 2]) >>> values[_] # Conversion to specific discrete values (the fact that values is a NumPy array is used for the indexing) [2.2, 3.3, 1.1, 3.3, 3.3, 1.1, 3.3, 2.2, 1.1, 3.3]

La distribución distrib arriba devuelve índices de la lista de values .

De manera más general, rv_discrete() toma una secuencia de valores enteros en los primeros elementos de su argumento values=(…,…) y devuelve estos valores, en este caso; no es necesario convertir a valores específicos (float). Aquí hay un ejemplo:

>>> values = [10, 20, 30] >>> probabilities = [0.2, 0.5, 0.3] >>> distrib = rv_discrete(values=(values, probabilities)) >>> distrib.rvs(size=10) array([20, 20, 20, 20, 20, 20, 20, 30, 20, 20])

donde los valores de entrada (enteros) se devuelven directamente con la probabilidad deseada.