ฉันจะสร้างตัวเลขสุ่มที่ไม่ซ้ำซากเป็นตัวเลขได้อย่างไร
list = np.random.random_integers(20,size=(10))
ฉันจะสร้างตัวเลขสุ่มที่ไม่ซ้ำซากเป็นตัวเลขได้อย่างไร
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
ฟังก์ชันเดิมแต่อาร์กิวเมนต์นี้ถูกนำไปใช้อย่างไม่มีประสิทธิภาพและปล่อยให้ไม่มีประสิทธิภาพเนื่องจากการรับประกันความเสถียรของสตรีมตัวเลขแบบสุ่มดังนั้นจึงไม่แนะนำให้ใช้ (โดยทั่วไปจะเป็นการสับเปลี่ยนและแบ่งชิ้นส่วนภายใน)
random.sample(range(n), 10))
จะมีประสิทธิภาพแม้ว่าจะมีขนาดใหญ่มากn
ก็ตามเนื่องจากrange
ออบเจ็กต์เป็นเพียง Wrapper ขนาดเล็กที่จัดเก็บค่าเริ่มต้นหยุดและขั้นตอน แต่จะไม่สร้างรายการจำนวนเต็มทั้งหมด ใน 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 ms สำหรับ a = 1M
n
ใช้งานขนาดใหญ่มากnumpy.random.Generator.choice
(เริ่มต้นด้วย numpy v1.17)
หลายปีต่อมามีเวลาในการเลือก 40000 จาก 10,000 ^ 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
(ทำไมต้องเลือก 40000 จาก 10,000 ^ 2 ในการสร้าง
เมทริกซ์scipy.sparse.randomขนาดใหญ่
- การใช้ scipy 1.4.1 np.random.choice( replace=False )
slooooow)
เคล็ดลับของหมวกสำหรับคนทั่วไป
คุณสามารถรับสิ่งนี้ได้โดยการจัดเรียงเช่นกัน:
random_numbers = np.random.random([num_samples, max_int])
samples = np.argsort(random_numbers, axis=1)
สามารถใช้การแปลงรายการชุด Python ได้ 10 หมายเลขที่ไม่ซ้ำกันระหว่าง 0 ถึง 20 สามารถรับได้ดังนี้:
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)
เพียงสร้างอาร์เรย์ที่มีช่วงของตัวเลขที่ต้องการจากนั้นสับเปลี่ยนโดยการสลับสุ่มซ้ำ ๆ กับองค์ประกอบที่ 0 ในอาร์เรย์ สิ่งนี้จะสร้างลำดับแบบสุ่มที่ไม่มีค่าซ้ำกัน