Python:从几何分布生成

时间:2014-07-07 14:34:09

标签: python numpy random

这是使用可能包含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"

2 个答案:

答案 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中获取大量值比单个调用更有效