Bagaimana cara menghasilkan nomor acak non-repetitif di numpy?
list = np.random.random_integers(20,size=(10))
Bagaimana cara menghasilkan nomor acak non-repetitif di numpy?
list = np.random.random_integers(20,size=(10))
Jawaban:
numpy.random.Generator.choice
menawarkan replace
argumen untuk diambil sampelnya tanpa penggantian:
from numpy.random import default_rng
rng = default_rng()
numbers = rng.choice(20, size=10, replace=False)
Jika Anda menggunakan NumPy di bawah 1.17, tanpa Generator
API, Anda dapat menggunakan random.sample()
dari pustaka standar:
print(random.sample(range(20), 10))
Anda juga dapat menggunakan numpy.random.shuffle()
dan mengiris, tetapi ini akan kurang efisien:
a = numpy.arange(20)
numpy.random.shuffle(a)
print a[:10]
Ada juga replace
argumen dalam numpy.random.choice
fungsi legacy , tetapi argumen ini diimplementasikan secara tidak efisien dan kemudian dibiarkan tidak efisien karena jaminan stabilitas aliran bilangan acak, jadi penggunaannya tidak disarankan. (Ini pada dasarnya melakukan hal shuffle-and-slice secara internal.)
random.sample(range(n), 10))
akan efisien bahkan untuk yang sangat besar n
, karena range
objek hanyalah pembungkus kecil yang menyimpan nilai awal, henti, dan langkah, tetapi tidak membuat daftar lengkap bilangan bulat. Di Python 2, Anda bisa mengganti range
dengan xrange
untuk mendapatkan perilaku serupa.
Saya pikir numpy.random.sample
tidak berfungsi sekarang. Ini cara saya:
import numpy as np
np.random.choice(range(20), 10, replace=False)
range(n)
(atau arange(n)
) sebagai argumen pertama choice
, itu setara dengan hanya lulus n
, misalnya choice(20, 10, replace=False)
.
np.random.choice(a, size, replace=False)
sangat lambat untuk ukuran besar a
- di komputer saya, sekitar 30 ms untuk a = 1M.
n
digunakan numpy.random.Generator.choice
(dimulai dengan v1.17 numpy)
Bertahun-tahun kemudian, beberapa waktu untuk memilih 40000 dari 10000 ^ 2 (Numpy 1.8.1, imac 2.7 GHz):
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
(Mengapa memilih 40000 dari 10.000 ^ 2? Untuk menghasilkan
matriks scipy.sparse.random yang besar
- penggunaan scipy 1.4.1 np.random.choice( replace=False )
, slooooow.)
Tip of the hat untuk orang numpy.random.
Konversi set list Python dapat digunakan. 10 angka unik antara 0 hingga 20 dapat diperoleh sebagai:
import numpy as np
import random
unique_numbers=set()
while(len(unique_numbers)<10):
unique_numbers.add(np.random.randint(0,20))
unique_numbers=list(unique_numbers)
random.shuffle(unique_numbers)
print(unique_numbers)
Cukup buat larik yang berisi rentang angka yang diperlukan, lalu kocok dengan berulang kali menukar angka acak dengan elemen ke-0 dalam larik. Ini menghasilkan urutan acak yang tidak mengandung nilai duplikat.