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

Create unequally spaced values from (superimposed) distributions

我想创建一个具有不等间距值的数组。间距应由(例如)两个具有不同平均值和宽度值的正态分布的叠加来确定。对于单个(正常)分布,我设法在这个 post 的帮助下得到了我想要的东西: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()

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

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

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

这是叠加分布的直方图的样子:

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

我还尝试定义一个新的分布,它继承自 rv_continuous class 从 scipy.stats,但我未能实现两个不同的 mean/width 参数。

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

提前感谢您的帮助and/or评论!

您可以子类化 rv_continuous 并提供一个 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()