Як я можу генерувати неповторювані випадкові числа в 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
об'єкт - це лише невелика обгортка, що зберігає значення start, stop і step, але не створює повного списку цілих чисел. У 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.)
Підказка капелюха numpy. випадкових людей.
Просто згенеруйте масив, що містить необхідний діапазон чисел, а потім перемішайте їх, повторно обміняючи випадковий номер 0-м елементом масиву. Це створює випадкову послідовність, яка не містить повторюваних значень.