例如:在numpy中,我如何從一個範圍中隨機選擇一個數字,排除之前選擇的隨機數字?
open_door = np.random.randint(1,4)
prize_behind_door = np.random.randint(1,4)
change_door = np.random.randint(1,4)
但我不想change_door有一個值是一樣的open_door,而它仍然是隨機的(所以它可以等於prize_behind_door),什麼命令我應該使用?
例如:在numpy中,我如何從一個範圍中隨機選擇一個數字,排除之前選擇的隨機數字?
open_door = np.random.randint(1,4)
prize_behind_door = np.random.randint(1,4)
change_door = np.random.randint(1,4)
但我不想change_door有一個值是一樣的open_door,而它仍然是隨機的(所以它可以等於prize_behind_door),什麼命令我應該使用?
使用np.setdiff1d
設置排除open_door
一個範圍,然後用np.random.choice
選擇關閉它一個隨機元素 -
np.random.choice(np.setdiff1d(range(1,4), open_door))
樣品試驗 -
In [329]: open_door = np.random.randint(1,4)
...: prize_behind_door = np.random.randint(1,4)
...:
In [330]: open_door
Out[330]: 2
In [331]: prize_behind_door
Out[331]: 1
In [349]: np.setdiff1d(range(1,4), open_door) # array that excludes open_door
Out[349]: array([1, 3])
In [332]: np.random.choice(np.setdiff1d(range(1,4), open_door))
Out[332]: 1
In [333]: np.random.choice(np.setdiff1d(range(1,4), open_door))
Out[333]: 3
In [334]: np.random.choice(np.setdiff1d(range(1,4), open_door))
Out[334]: 3
In [335]: np.random.choice(np.setdiff1d(range(1,4), open_door))
Out[335]: 3
In [336]: np.random.choice(np.setdiff1d(range(1,4), open_door))
Out[336]: 1
如何choice
沒有replace
?
In [230]: np.random.choice(range(1,4),2, replace=False)
Out[230]: array([2, 3])
In [231]: np.random.choice(range(1,4),2, replace=False)
Out[231]: array([2, 3])
In [232]: np.random.choice(range(1,4),2, replace=False)
Out[232]: array([1, 3])
In [233]: np.random.choice(range(1,4),2, replace=False)
Out[233]: array([1, 2])
In [234]: np.random.choice(range(1,4),2, replace=False)
Out[234]: array([3, 2])
In [235]: np.random.choice(range(1,4),2, replace=False)
Out[235]: array([3, 2])
In [236]: open_door, change_door = np.random.choice(range(1,4),2, replace=False)
...:
In [237]: open_door
Out[237]: 3
In [238]: change_door
Out[238]: 1
2值將是隨機的,但總是不同。這個選擇將獨立於prize_behind_door
。
對於從一個小範圍的這樣的2個值,Python的random
模塊將是一樣好,如果沒有更好的(快的時間測試表明它的速度更快):
random.sample(range(1,4),2)
'replace = False'有一個[確實糟糕的實現](https://github.com/numpy/numpy/blob/34075a54e7aa10e80d41ef33ec7102292ecff0d5/numpy/random/mtrand/mtrand.pyx#L1185),我認爲它們被卡住了爲了向後兼容的原因。從'range(1,4)'中選擇是可以的,但對於大型陣列的小樣本來說,它可能是一個嚴重的性能殺手。 – user2357112
你喜歡'random.sample'嗎? – hpaulj
'random.sample'對於如何生成樣本更聰明。哪一個表現更好取決於具體的參數;我可能更喜歡這種情況。 – user2357112
我會用while循環
open_door = np.random.randint(1,4)
prize_behind_door = np.random.randint(1,4)
while True:
x = np.random.randint(1,4)
if x != open_door:
change_door = x
break
如果你想disclude多個值,你可以只添加if語句
if x != value_1 and x != value_2:
value_3 = x
break
另一種方法是創建一個長度與隨機數範圍相同的布爾數組。
如果布爾型數組的索引值爲False,則表示該值尚未被選中,如果它爲true,則表示它已經存在。
在while循環中檢查是否通過獲取bool_array [chosen_number]的結果來選擇值。如果它已被忽略並選擇一個新的數字,否則將該值附加到您用於表示值的數組,並將該數字的索引的布爾值數組設置爲True以表示它現在被選中。
我會做這樣一個函數內保持一切井井有條
from random import randint
def select_random_numbers(rand_range, values):
temp_list = []
isPicked = [False for _ in range(rand_range)]
for i in range(values):
while True:
x = randint(0, rand_range - 1)
if isPicked[x] == False:
temp_list.append(x)
isPicked[x] = True
break
return(temp_list)
print(select_random_numbers(10, 5))
謝謝你,這是一個非常簡潔的回答。如果我想排除之前隨機選擇的兩個數字,該怎麼辦?例如,現在範圍是(1,8),我隨機選擇兩個數字。然後我選擇第三個數字,應該隨機選擇,不包括前兩個數字。 – hephaes
@hephaes使用'np.setdiff1d(range(1,8),open_door)',其中'open_door'將前兩個選擇的值作爲包含這兩個元素的列表或數組,並且再次使用'np.random.choice'在它上面:'np.random.choice(np.setdiff1d(range(1,8),open_door))'。所以,沒有什麼變化。 – Divakar