Как я могу генерировать неповторяющиеся случайные числа в numpy?
list = np.random.random_integers(20,size=(10))
Как я могу генерировать неповторяющиеся случайные числа в numpy?
list = np.random.random_integers(20,size=(10))
Ответы:
numpy.random.Generator.choice
предлагает replace
аргумент к образцу без замены:
from numpy.random import default_rng
rng = default_rng()
numbers = rng.choice(20, size=10, replace=False)
Если вы используете NumPy до 1.17, без Generator
API, вы можете использовать random.sample()
из стандартной библиотеки:
print(random.sample(range(20), 10))
Вы также можете использовать numpy.random.shuffle()
и нарезку, но это будет менее эффективно:
a = numpy.arange(20)
numpy.random.shuffle(a)
print a[:10]
В replace
унаследованной numpy.random.choice
функции также есть аргумент , но этот аргумент был реализован неэффективно, а затем оставлен неэффективным из-за гарантий стабильности потока случайных чисел, поэтому его использование не рекомендуется. (Он в основном выполняет функцию перемешивания и нарезки внутри.)
import random
?
random.sample(range(n), 10))
будет эффективен даже для очень больших n
, поскольку range
объект - это просто небольшая оболочка, хранящая значения начала, остановки и шага, но не создающая полный список целых чисел. В Python 2 вы можете заменить range
на, xrange
чтобы получить аналогичное поведение.
Думаю, numpy.random.sample
сейчас не работает. Это мой путь:
import numpy as np
np.random.choice(range(20), 10, replace=False)
range(n)
(или arange(n)
) в качестве первого аргумента choice
эквивалентно просто передать n
, например choice(20, 10, replace=False)
.
np.random.choice(a, size, replace=False)
это очень медленно для больших a
- на моей машине около 30 мс для a = 1M.
n
использовании numpy.random.Generator.choice
(начиная с numpy v1.17)
Спустя некоторое время для выбора 40000 из 10000 ^ 2 (Numpy 1.8.1, imac 2.7 ГГц):
import random
import numpy as np
n = 10000
k = 4
np.random.seed( 0 )
%timeit np.random.choice( n**2, k * n, replace=True ) # 536 µs ± 1.58 µs
%timeit np.random.choice( n**2, k * n, replace=False ) # 6.1 s ± 9.91 ms
# https://docs.scipy.org/doc/numpy/reference/random/index.html
randomstate = np.random.default_rng( 0 )
%timeit randomstate.choice( n**2, k * n, replace=False, shuffle=False ) # 766 µs ± 2.18 µs
%timeit randomstate.choice( n**2, k * n, replace=False, shuffle=True ) # 1.05 ms ± 1.41 µs
%timeit random.sample( range( n**2 ), k * n ) # 47.3 ms ± 134 µs
(Почему выбирают 40000 из 10000 ^ 2? Для создания больших
scipy.sparse.random
матриц - scipy 1.4.1 использует np.random.choice( replace=False )
, slooooow.)
Совет перед множеством случайных людей.
Просто сгенерируйте массив, содержащий требуемый диапазон чисел, затем перемешайте их, многократно меняя местами случайное число с 0-м элементом в массиве. Это создает случайную последовательность, не содержащую повторяющихся значений.