python正态分布随机数_python-2.7 – 使用numpy从偏斜正态分布中生成N个随机数

我首先生成PDF曲线以供参考:

NUM_SAMPLES = 100000

SKEW_PARAMS = [-3, 0]

def skew_norm_pdf(x,e=0,w=1,a=0):

# adapated from:

# https://stackoverflow.com/questions/5884768/skew-normal-distribution-in-scipy

t = (x-e) / w

return 2.0 * w * stats.norm.pdf(t) * stats.norm.cdf(a*t)

# generate the skew normal PDF for reference:

location = 0.0

scale = 1.0

x = np.linspace(-5,5,100)

plt.subplots(figsize=(12,4))

for alpha_skew in SKEW_PARAMS:

p = skew_norm_pdf(x,location,scale,alpha_skew)

# n.b. note that alpha is a parameter that controls skew, but the 'skewness'

# as measured will be different. see the wikipedia page:

# https://en.wikipedia.org/wiki/Skew_normal_distribution

plt.plot(x,p)

OOmUd.png

接下来,我发现了一个从偏斜正态分布中采样随机数的VB实现,并将其转换为python:

# literal adaption from:

# https://stackoverflow.com/questions/4643285/how-to-generate-random-numbers-that-follow-skew-normal-distribution-in-matlab

# original at:

# http://www.ozgrid.com/forum/showthread.php?t=108175

def rand_skew_norm(fAlpha, fLocation, fScale):

sigma = fAlpha / np.sqrt(1.0 + fAlpha**2)

afRN = np.random.randn(2)

u0 = afRN[0]

v = afRN[1]

u1 = sigma*u0 + np.sqrt(1.0 -sigma**2) * v

if u0 >= 0:

return u1*fScale + fLocation

return (-u1)*fScale + fLocation

def randn_skew(N, skew=0.0):

return [rand_skew_norm(skew, 0, 1) for x in range(N)]

# lets check they at least visually match the PDF:

plt.subplots(figsize=(12,4))

for alpha_skew in SKEW_PARAMS:

p = randn_skew(NUM_SAMPLES, alpha_skew)

sns.distplot(p)

QzBFV.png

然后写了一个快速版本(没有经过大量测试)似乎是正确的:

def randn_skew_fast(N, alpha=0.0, loc=0.0, scale=1.0):

sigma = alpha / np.sqrt(1.0 + alpha**2)

u0 = np.random.randn(N)

v = np.random.randn(N)

u1 = (sigma*u0 + np.sqrt(1.0 - sigma**2)*v) * scale

u1[u0 < 0] *= -1

u1 = u1 + loc

return u1

# lets check again

plt.subplots(figsize=(12,4))

for alpha_skew in SKEW_PARAMS:

p = randn_skew_fast(NUM_SAMPLES, alpha_skew)

sns.distplot(p)

Z9qT8.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值