这是使用可能包含0的参数数组从几何分布生成随机数的最佳方法还是最有效的方法吗?
allids["c"]=[2,0,1,1,3,0,0,2,0]
[ 0 if x == 0 else numpy.random.geometric(1./x) for x in allids["c"]]
注意我有点担心优化。
编辑:
一些上下文:我有一系列字符(即ATCGGGA),我想扩展/收缩单个字符的运行(即如果原始序列有2个' A' s我想模拟一个预期值为2' A的序列,但根据几何分布而变化。所有运行长度为1的字符我都不希望长度可变。
所以,如果
seq = 'AATCGGGAA'
allids["c"]=[2,0,1,1,3,0,0,2,0]
rep=[ 0 if x == 0 else numpy.random.geometric(1./x) for x in allids["c"]]
"".join([s*r for r, s in zip(rep, seq)])
将输出(当rep
为[1, 0, 1, 1, 3, 0, 0, 1, 0]
时)
"ATCGGGA"
答案 0 :(得分:2)
您可以使用masked array来避免除以零。
import numpy as np
a = np.ma.masked_equal([2, 0, 1, 1, 3, 0, 0, 2, 0], 0)
rep = np.random.geometric(1. / a)
rep[a.mask] = 0
这会为a
的每个元素生成一个随机样本,然后稍后删除其中的一些元素。如果您担心这种随机数的浪费,您可以产生足够的效果,如下所示:
import numpy as np
a = np.ma.masked_equal([2, 0, 1, 1, 3, 0, 0, 2, 0], 0)
rep = np.zeros(a.shape, dtype=int)
rep[~a.mask] = np.random.geometric(1. / a[~a.mask])
答案 1 :(得分:1)
这个怎么样:
counts = array([2, 0, 1, 1, 3, 0, 0, 2, 0], dtype=float)
counts_ma = numpy.ma.array(counts, mask=(counts == 0))
counts[logical_not(counts.mask)] = \
array([numpy.random.geometric(v) for v in 1.0 / counts[logical_not(counts.mask)]])
您可以预先计算均聚物运行的分布,并将调用次数限制为geometric
,因为从RNG中获取大量值比单个调用更有效