回答
map函數也適用於布爾數組。您可以在子樣本邏輯添加到您的功能,像這樣:
import numpy as np
rate = 0.2
f = lambda x: np.random.choice((True, x),1,p=[rate,1-rate])[0]
a = np.array([0,0,1,0,1], dtype='bool')
map(f, a)
# This will output array a with on average 20% of the elements changed to "1"
# it can be slightly more or less than 20%, by chance.
或者你可以重寫一個地圖功能,像這樣:
import numpy as np
def map_bitarray(f, b, rate):
'''
maps function f on a random subset of b
:param f: the function, should take a binary array of size <= len(b)
:param b: the binary array
:param rate: the fraction of elements that will be replaced
:return: the modified binary array
'''
c = np.copy(b)
num_elem = len(c)
idx = np.random.choice(range(num_elem), num_elem*rate, replace=False)
c[idx] = f(c[idx])
return c
f = lambda x: True
b = np.array([0,0,1,0,1], dtype='bool')
map_bitarray(f, b, 0.2)
# This will output array b with exactly 20% of the elements changed to "1"
有兩件事:首先,我有時會得到'[False False True False True]'的輸出,其中沒有元素被改變。其次,這不允許將'False'轉換爲'True'。後者可能不是一個問題,因爲OP不清楚這是否可能。 –
在第一個選項中,平均爲20%,這意味着可能會出現多於或少於20%的元素髮生變化的情況。第二個選項總是給你20%的準確率(或者你要求的任何比率)。在40%的情況下,你看到'[False False True False True]'是因爲'True'被設置爲'True'(沒有改變)。 OP可以在lambda中設置他想要的任何函數,例如這個:'f = lambda x:not(x)'。 – Bastiaan
更正:'f = lambda a:np.logical_not(x)' – Bastiaan
rate=0.2
repeats=5
seed=[0,0,1,0,1]
realizations=np.tile(seed,[repeats,1])^np.random.binomial(1,rate,[repeats,len(seed)])
使用np.tile()
以產生從所述種子行的矩陣。
np.random.binomial()
用您的請求速率生成二項掩碼矩陣。
運用面具與XOR二進制運算^
編輯:
基於@Jared Goguen評論,如果你想改變位的20%,可以說明以口罩選擇要隨機更改的元素:
seed=[1,0,1,0,1]
rate=0.2
repeats=10
mask_list=[]
for _ in xrange(repeats):
y=np.zeros(len(seed),np.int32)
y[np.random.choice(len(seed),0.2*len(seed))]=1
mask_list.append(y)
mask = np.vstack(mask_list)
realizations=np.tile(seed,[repeats,1])^mask
應該指出,這並不改變0.2的條目的比例,而是每個元素有0.2的機會改變。平均重新排列將會有0.2個元素的比例發生變化,但是每個重新排列可能在沒有元素髮生變化並且所有元素髮生變化的地方都有。這個實現完美地模擬了每個元素具有*獨立*轉換概率的結構,但是如果知道具有兩個1的5個陣列將以三個1轉換爲5個陣列,則它失敗。 –
感謝您指出。另一種情況將用馬爾可夫鏈建模,不是嗎? – xvan
對於馬爾可夫鏈,轉換矩陣由每個狀態轉換到其他狀態的概率組成。根據定義,在這個過程中狀態向量的總和是不變的,所以我真的沒有看到使用馬爾可夫鏈對此進行建模的方法。可能有辦法使用類似的過程,但轉換矩陣不會是隨機的。 –
所以,已經有一個答案提供了序列,其中每個元素都有一個隨機轉移概率。但是,您似乎可能想要改變一些確切的元素部分。例如,[1, 0, 0, 1, 0]
可以更改爲[1, 1, 0, 1, 0]
或[0, 0, 0, 1, 0]
,但不是[1, 1, 1, 1, 0]
。
基於xvan的回答,前提是使用按位異或運算符^
。當一位與0異或時,它的值不會改變。當一個位與1相異時,它會翻轉。從你的問題來看,你似乎想改變序列中的len(seq)*rate
位數。首先創建mask
其中包含len(seq)*rate
的數字1。爲了得到一個改變的序列,用洗牌版本mask
對原始序列進行異或。
這裏有一個簡單的,低效率的實現:
import numpy as np
def edit_sequence(seq, rate, count):
length = len(seq)
change = int(length * rate)
mask = [0]*(length - change) + [1]*change
return [seq^np.random.permutation(mask) for _ in range(count)]
rate = 0.2
seq = np.array([0, 0, 1, 0, 1])
print edit_sequence(seq, rate, 5)
# [0, 0, 1, 0, 0]
# [0, 1, 1, 0, 1]
# [1, 0, 1, 0, 1]
# [0, 1, 1, 0, 1]
# [0, 0, 0, 0, 1]
我真的不知道很多關於NumPy的,所以也許更有經驗的人可以使這個效率,但這種方法似乎固體。
編輯:這裏有一個版本的情況下約30%的速度:
def edit_sequence(seq, rate, count):
mask = np.zeros(len(seq), dtype=int)
mask[:len(seq)*rate] = 1
output = []
for _ in range(count):
np.random.shuffle(mask)
output.append(seq^mask)
return output
看來,這個更新版本擴展得很好的seq
的大小和count
值。在seq
和mask
中使用dtype=bool
會使時間進一步縮短50%。
- 1. 隨機化或隨機的陣列
- 2. 陣列中的不一致隨機化
- 3. numpy的:分割陣列隨機
- 4. 矩陣的半隨機化
- 5. 部分隨機化的PHP數組
- 6. 隨機化元素位置到陣列
- 7. 隨機化一個隊列
- 8. 從隨機陣列
- 9. 隨機miltidimentional陣列
- 10. 從隨機陣列
- 11. 與「隨機」陣列
- 12. PHP隨機陣列
- 13. 陣列隨機數
- 14. 隨機化列
- 15. 把隨機數隨機分爲2D陣列
- 16. 用組件百分比隨機化陣列
- 17. 創建的隨機真一陣列/假
- 18. 隨機位置的陣列
- 19. 隨機抽樣的陣列
- 20. 陣列的隨機NSNumber
- 21. 隨機的OBJ和陣列
- 22. 隨機化序列
- 23. C++向量隨機隨機洗牌的一部分
- 24. 隨機矩陣的Numpy陣列
- 25. 隨機化PHP對象數組的一部分
- 26. 隨機化一個雙精度的小數部分
- 27. Javascript:使其一個隨機陣列
- 28. 隨機化HMTL5視頻陣列只播放一個視頻
- 29. 隨機隨機化項目列表
- 30. 隨機數組到陣列
顯示你有 – JBernardo
代碼所以,如果你有一個數組A的二進制值,數組中的每個索引都有一個概率P?例如,你的模式[0 0 1 0 1]可以變爲[1 1 1 1 1],即使這樣做不可能嗎? – Carser