从(叠加)分布创建不等间距的值
Posted
技术标签:
【中文标题】从(叠加)分布创建不等间距的值【英文标题】:Create unequally spaced values from (superimposed) distributions 【发布时间】:2021-04-02 00:00:47 【问题描述】:我想创建一个具有不等间距值的数组。间距应由(例如)具有不同平均值和宽度值的两个正态分布的叠加来确定。对于单个(正常)发行版,我在这篇文章的帮助下设法得到了我想要的东西: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
类继承自scipy.stats
的新分布,但我未能实现两个不同的均值/宽度参数。
我很确定它应该可以添加单个概率密度函数,但不幸的是我也用这种方法失败了。
提前感谢您的任何帮助和/或评论!
【问题讨论】:
当您说“将它们加在一起”时,您的意思是添加 numpy 数组还是像这样覆盖它们 vals = np.array(list(dist1.ppf(pp)) + list(dist2.ppf( pp)))?这似乎是您正在寻找的(如果需要,可以添加处理相同的条目)? 【参考方案1】:您可以继承 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()
【讨论】:
感谢您的回答顺便说一句。帮了我很多!对于类似的应用程序,我需要从这样的分布中抽取随机数。不幸的是,为此使用dist.rvs(size=n)
非常慢。我为此Speed up drawing random values from superimposed truncated normal distributions 创建了一个新问题,并认为您也可以在这里提供帮助?再次感谢!以上是关于从(叠加)分布创建不等间距的值的主要内容,如果未能解决你的问题,请参考以下文章