Python: 带有均值和标准差的随机数生成器

13

我需要知道如何在Python中生成1000个随机数,范围在500到600之间,且平均值为550,标准差为30。

import pylab
import random

xrandn = pylab.zeros(1000,float)

for j in range(500,601):
xrandn[j] = pylab.randn()

???????

1
你想从哪个分布中绘制它?我的初步猜测是从标准差为30的随机分布中绘制,并且丢弃所有小于500或大于600的元素。然而,这样做会降低标准差。 - physicalattraction
3个回答

14

你正在寻找 stats.truncnorm:


import scipy.stats as stats

a, b = 500, 600
mu, sigma = 550, 30
dist = stats.truncnorm((a - mu) / sigma, (b - mu) / sigma, loc=mu, scale=sigma)

values = dist.rvs(1000)

1
(如果使用Python 2,请添加一些“.0”) - DSM
5
这个参数设定是否正确用于方差?结果中的values.std()看起来是 ~23.87,而不是30。 - DSM
标准库并不完全符合原始问题的要求。 - Louie Lee

10

针对您的问题,还有其他选择。维基百科上有一份带有有限间隔的连续分布列表,根据不同的分布,您可以通过合适的参数获得所需的特性。例如,如果您需要类似于“有界高斯钟形曲线”(非截断),则可以选择(缩放后的)Beta分布

import numpy as np
import scipy.stats
import matplotlib.pyplot as plt

def my_distribution(min_val, max_val, mean, std):
    scale = max_val - min_val
    location = min_val
    # Mean and standard deviation of the unscaled beta distribution
    unscaled_mean = (mean - min_val) / scale
    unscaled_var = (std / scale) ** 2
    # Computation of alpha and beta can be derived from mean and variance formulas
    t = unscaled_mean / (1 - unscaled_mean)
    beta = ((t / unscaled_var) - (t * t) - (2 * t) - 1) / ((t * t * t) + (3 * t * t) + (3 * t) + 1)
    alpha = beta * t
    # Not all parameters may produce a valid distribution
    if alpha <= 0 or beta <= 0:
        raise ValueError('Cannot create distribution for the given parameters.')
    # Make scaled beta distribution with computed parameters
    return scipy.stats.beta(alpha, beta, scale=scale, loc=location)

np.random.seed(100)

min_val = 1.5
max_val = 35
mean = 9.87
std = 3.1
my_dist = my_distribution(min_val, max_val, mean, std)
# Plot distribution PDF
x = np.linspace(min_val, max_val, 100)
plt.plot(x, my_dist.pdf(x))
# Stats
print('mean:', my_dist.mean(), 'std:', my_dist.std())
# Get a large sample to check bounds
sample = my_dist.rvs(size=100000)
print('min:', sample.min(), 'max:', sample.max())

输出:

mean: 9.87 std: 3.100000000000001
min: 1.9290674232087306 max: 25.03903889816994

概率密度函数图:

概率密度函数

请注意,在这种情况下,并非每个边界、平均值和标准偏差的可能组合都会产生有效的分布,取决于 alphabeta 的结果值,概率密度函数可能看起来像一个“反向钟形”(即使平均值和标准偏差仍然是正确的)。


3

我不确定原帖作者想要什么,但如果他只想要一个满足下图的数组xrandn,下面是实现步骤:

enter image description here

首先,创建一个标准分布(高斯分布),最简单的方法可能是使用numpy:

import numpy as np
random_nums = np.random.normal(loc=550, scale=30, size=1000)

接着,您可以使用列表推导式仅保留所需范围内的数字:

random_nums_filtered = [i for i in random_nums if i>500 and i<600]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接