Python 2.7 使用numpy从斜正态分布生成N个随机数

Python 2.7 使用numpy从斜正态分布生成N个随机数,python-2.7,numpy,random,Python 2.7,Numpy,Random,我需要python中的一个函数来返回N个来自歪正态分布的随机数。需要将倾斜作为一个参数 e、 我目前的用途是 x=numpy.random.randn(1000) 理想的函数是,例如 x=randn\u skew(1000,skew=0.7) 解决方案需要符合:python版本2.7,numpy v.1.9 这里有一个类似的答案:但是这会生成PDF而不是随机数。我首先生成PDF曲线以供参考: NUM_SAMPLES = 100000 SKEW_PARAMS = [-3, 0] def skew

我需要python中的一个函数来返回N个来自歪正态分布的随机数。需要将倾斜作为一个参数

e、 我目前的用途是

x=numpy.random.randn(1000)

理想的函数是,例如

x=randn\u skew(1000,skew=0.7)

解决方案需要符合:python版本2.7,numpy v.1.9


这里有一个类似的答案:但是这会生成PDF而不是随机数。

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

NUM_SAMPLES = 100000
SKEW_PARAMS = [-3, 0]

def skew_norm_pdf(x,e=0,w=1,a=0):
    # adapated from:
    # http://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)

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

# literal adaption from:
# http://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)

然后写了一个快速版本(无需大量测试),看起来是正确的:

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)
def randn\u skew\u fast(N,alpha=0.0,loc=0.0,scale=1.0):
西格玛=α/np.sqrt(1.0+α**2)
u0=np.random.randn(N)
v=np.random.randn(N)
u1=(西格玛*u0+np.sqrt(1.0-西格玛**2)*v)*量表
u1[u0<0]*=-1
u1=u1+loc
返回u1
#让我们再检查一下
plt.子地块(figsize=(12,4))
对于倾斜参数中的alpha_倾斜:
p=randn\u-skew\u-fast(样本数,α-skew)
sns.distplot(p)

改编自fGarch R软件包的rsnorm功能

def random_snorm(n, mean = 0, sd = 1, xi = 1.5):
    def random_snorm_aux(n, xi):
        weight = xi/(xi + 1/xi)
        z = numpy.random.uniform(-weight,1-weight,n)
        xi_ = xi**numpy.sign(z)
        random = -numpy.absolute(numpy.random.normal(0,1,n))/xi_ * numpy.sign(z)
        m1 = 2/numpy.sqrt(2 * numpy.pi)
        mu = m1 * (xi - 1/xi)
        sigma = numpy.sqrt((1 - m1**2) * (xi**2 + 1/xi**2) + 2 * m1**2 - 1)
        return (random - mu)/sigma

    return random_snorm_aux(n, xi) * sd + mean
这里,a是一个参数,您可以参考:

您提出了请求,但这是一个问答网站,您的问题是什么?我们将帮助您解决编码时遇到的问题,但不只是为您编写代码。您想生成遵循分布的随机数吗?我尝试这样做时会收到噪音p=random_snrom(n,5.61594709,3.73888096,1.62537967)x=linspace(-10100,n)plt.plot(x,p),或者我如何检查结果?这很好,但这个问题最初是针对努比的。
from scipy.stats import skewnorm
a=10
data= skewnorm.rvs(a, size=1000)