Quiero generar N enteros aleatorios, donde el primer entero se elige uniformemente de 0..N, el segundo se elige uniformemente de 0 .. (N-1), el tercero de 0 .. (N-2), y así en. ¿Hay alguna manera de hacer esto rápidamente en numpy, sin incurrir en el costo de realizar una llamada numpy por separado N veces?

0
user2667066 25 jun. 2020 a las 16:23

2 respuestas

La mejor respuesta

Puede pasar matrices como argumentos al método integers de la clase de generador aleatorio de numpy. Los argumentos se difundirán y generarán los valores apropiados.

Por ejemplo,

In [17]: import numpy as np                                        

In [18]: rng = np.random.default_rng()

In [19]: N = 16                                                                                                           

In [20]: rng.integers(0, np.arange(N, 0, -1))                                        
Out[20]: array([13, 10, 11, 11,  9,  8,  3,  0,  2,  5,  3,  1,  0,  2,  0,  0])

Tenga en cuenta que el valor superior dado al método integers está excluido, por lo que si los rangos que indicó son inclusivos, tendrá que ajustar los argumentos arange adecuadamente:

In [24]: rng.integers(0, np.arange(N+1, 1, -1))                                                                           
Out[24]: array([ 6,  9, 11, 11,  7,  2,  5,  5,  8,  7,  5,  5,  4,  0,  1,  0])
1
Warren Weckesser 25 jun. 2020 a las 13:36

Podemos muestrear números aleatorios uniformemente en (0,1) y escalar, luego convertir a int:

N = 10
np.random.seed(10)
randoms = np.random.rand(N)

(randoms * np.arange(1,N+1)).astype(int)

Salida:

array([0, 0, 1, 2, 2, 1, 1, 6, 1, 0])
1
Quang Hoang 25 jun. 2020 a las 13:27