从叠加分布创建不等距的值

问题描述

我想创建一个具有不等距值的数组。间距应由(例如)具有不同均值和宽度值的两个正态分布的叠加确定。对于单个(正态)分布,我在这文章的帮助下设法得到了我想要的:python,weighted linspace

使用此代码

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

dist = stats.norm(loc=1.2,scale=0.6)
bounds = dist.cdf([0,2])
pp = np.linspace(*bounds,num=21)
vals = dist.ppf(pp)

plt.plot(vals,[1]*vals.size,'o')
plt.show()

我得到了我想要的单一分布的结果:

enter image description here

但是,对于两个正态分布的叠加,我需要完全相同,例如:

dist1 = stats.norm(loc=3,scale=2)
dist2 = stats.norm(loc=1.2,scale=0.6)

叠加分布的直方图如下所示:

enter image description here

作为临时解决方案,我分别为每个发行版创建了数组并将它们添加在一起。但是,这并不是我想要的,因为添加两个单独的数组会导致添加的数组之间的步长波动(例如,可能会发生来自两个不同(单独)数组的两个值几乎或完全相同)。

我还尝试定义一个rv_continuous 继承的 scipy.stats 类的新分布,但我未能实现两个不同的均值/宽度参数。

我很确定它应该可以添加单个概率密度函数,但不幸的是我也用这种方法失败了。

预先感谢您的任何帮助和/或评论

解决方法

您可以子类化 rv_continuous 并提供一个 pdf,该 pdf 是两个给定 pdf 的平均值。

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

class sum_gaussians_gen(stats.rv_continuous):
    def _pdf(self,x):
        return (stats.norm.pdf(x,loc=3,scale=2) + stats.norm.pdf(x,loc=1.2,scale=0.6)) / 2

dist = sum_gaussians_gen()
bounds = dist.cdf([0,7])
pp = np.linspace(*bounds,num=21)
vals = dist.ppf(pp)

plt.plot(vals,[0.5] * vals.size,'o')
xs = np.linspace(0,7,500)
plt.plot(xs,dist.pdf(xs))
plt.ylim(ymin=0)
plt.show()

resulting plot