回答
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. numpy的:分割阵列随机
- 3. 随机化元素位置到阵列
- 4. 从随机阵列
- 5. PHP随机阵列
- 6. 阵列随机数
- 7. 用组件百分比随机化阵列
- 8. 创建的随机真一阵列/假
- 9. 阵列的随机NSNumber
- 10. 随机化序列
- 11. C++向量随机随机洗牌的一部分
- 12. 随机化一个双精度的小数部分
- 13. PHP - 多线随机阵列
- 14. 随机删除阵列
- 15. PHP返回随机阵列
- 16. 随机数排序阵列
- 17. 随机选择矩阵列
- 18. 仅回显阵列外部的阵列的一部分
- 19. 在其他阵列上随机显示一个阵列
- 20. 随机化与依赖阵列的阵列,然后让它们发布的HTML
- 21. 随机分裂阵列的列表在Python
- 22. 创建一个部分洗牌的随机数排序列表
- 23. 整数矩阵到随机矩阵归一化
- 24. 随机化和分层树
- 25. 复制的阵列的一部分到另一阵列
- 26. 随机化一个列表,但范围
- 27. 的JavaScript/jQuery的:阵列随机问题
- 28. 随机格阵列变化以2秒的
- 29. PHP阵列随机化但不复制的花名册
- 30. 阵列随机结构(AOS)与数组(SOA)结构的量化
显示你有 – JBernardo
代码所以,如果你有一个数组A的二进制值,数组中的每个索引都有一个概率P?例如,你的模式[0 0 1 0 1]可以变为[1 1 1 1 1],即使这样做不可能吗? – Carser