Python 3.x 从截断高斯分布生成numpy矢量值

Python 3.x 从截断高斯分布生成numpy矢量值,python-3.x,numpy,normal-distribution,truncation,Python 3.x,Numpy,Normal Distribution,Truncation,我有一个函数,它从截短的正态分布生成一个值,它有一个while循环,可以确保在截短之外生成的任何值都会被丢弃并替换为另一个值,直到它位于范围之内 def gen_truncated(minimum, maximum, ave, sigma): # min=0.9, max=1, x = 0. while x < minimum or x > maximum: x = np.random.normal(0,1)*sigma+ave r

我有一个函数,它从截短的正态分布生成一个值,它有一个while循环,可以确保在截短之外生成的任何值都会被丢弃并替换为另一个值,直到它位于范围之内

def gen_truncated(minimum, maximum, ave, sigma):
    # min=0.9, max=1, 
    x = 0.
    while x < minimum or x > maximum:
        x = np.random.normal(0,1)*sigma+ave

    return x
通道的示例运行

gen_channel(0.05, 0.05, 0.98, 0.15)
我会举个例子

Out[140]: 
array([[ 1.        +0.j,  0.        +0.j,  0.        +0.j,
         0.        +0.j],
       [-0.05828008+0.j,  0.91805971+0.j,  0.14291751+0.j,
        -0.00946994+0.j],
       [-0.00509449+0.j, -0.14170308+0.j,  0.90034613+0.j,
        -0.11548884+0.j],
       [ 0.0467522 +0.j, -0.00851749+0.j,  0.11450963+0.j,
         0.90259637+0.j]])
现在,如果我想创建100个4x4矩阵,我必须使用列表理解,即

np.array([gen_channel(0.05, 0.05, 0.98, 0.15) for i in range(100)])

将运行所有约束比较,并逐个创建4x4矩阵。我最初的问题是因为我想把它们矢量化,所以不是一次比较一个值,只需使用numpy broadcast生成一个值数组,并检查约束,这样我就有了一个向量版本的
gen_channel
,它可以生成100个这样的4x4矩阵,而无需理解列表。列表理解方式包含重复使用生成单个随机数,这导致其运行速度出现瓶颈。我想做的是生成随机数数组,进行这些检查,然后生成4x4通道数组,以减少瓶颈。

您可以从原始分布中提取一个大样本,然后确定哪些条目位于正确的范围内,然后从中提取:

# parameters
ave, sigma = 0,1
minimum, maximum = 0.9, 1

# draw sample and specify which entries are ok
a = np.random.normal(ave, sigma, 100000)
index = (a > minimum) & (a < maximum)

# draw from subset
np.random.choice(a[index], 1000, replace=False)
在循环中的原始文件上:

%%timeit -r 10 -n 10

for i in range(1000):
    gen_truncated(0.9,1, 0, 1)

88.5 ms ± 1.24 ms per loop (mean ± std. dev. of 10 runs, 10 loops each)

这会减少调用我的函数
1000次的开销吗?只要我不画太多的完整样本?如果完整样本中没有足够的元素满足条件,并且不足以形成我的子集,该怎么办?@user3613025请参见编辑。我想如果你担心样本数量,你可以检查
索引
的总和是否至少是你的子集的长度。它看起来与我想要的完全一样,但我想确保它与我的整个算法一起工作,然后再接受你的回答。请查看我更新的问题,如果我的问题变得比原来更复杂,我很抱歉。
%%timeit -r 10 -n 10 
2.51 ms ± 87.5 µs per loop (mean ± std. dev. of 10 runs, 10 loops each)
%%timeit -r 10 -n 10

for i in range(1000):
    gen_truncated(0.9,1, 0, 1)

88.5 ms ± 1.24 ms per loop (mean ± std. dev. of 10 runs, 10 loops each)