如何获取有界的python scipy类型连续rv分布对象?

如何获取有界的python scipy类型连续rv分布对象?,python,scipy,statistics,distribution,Python,Scipy,Statistics,Distribution,我想定义一个连续随机变量分布的有界版本(比如,指数分布,但我可能还想使用其他分布)。边界是0和1。我想 绘制随机变量(由scipy.stats.rv\u continuous.rvs完成) 使用ppf(百分点函数)(由scipy.stats.rv_continuous.ppf完成),并且可能 使用cdf(累积密度函数)(如scipy.stats.rv_continuous.cdf所做) 我能想到的可能方法: 以特殊方式获取随机变量并不困难 import scipy.stats d = scip

我想定义一个连续随机变量分布的有界版本(比如,指数分布,但我可能还想使用其他分布)。边界是0和1。我想

  • 绘制随机变量(由
    scipy.stats.rv\u continuous.rvs
    完成)
  • 使用ppf(百分点函数)(由
    scipy.stats.rv_continuous.ppf
    完成),并且可能
  • 使用cdf(累积密度函数)(如scipy.stats.rv_continuous.cdf所做)
  • 我能想到的可能方法:

    • 以特殊方式获取随机变量并不困难

      import scipy.stats
      d = scipy.stats.expon(0, 3/10.)    # an exponential distribution as an example 
      rv = d.rvs(size=target_number_of_rv)
      rv = rv[0=<rv]
      rv = rv[rv<=1]
      while len(rv) < target_number_of_rv:
          rv += d.rvs(1)
          rv = rv[0=<rv]
          rv = rv[rv<=1]
      
      导入scipy.stats
      d=scipy.stats.expon(0,3/10)#以指数分布为例
      rv=d.rvs(尺寸=rv的目标数量)
      
      rv=rv[0=如果分布是
      scipy.stats
      中可用的分布之一,则可以使用该分布的cdf计算其在两个边界之间的积分。否则,可以定义
      rv_continuous
      的pdf,然后使用其cdf获得该积分

      现在,实际上,您已经得到了所需pdf的有界版本的pdf,因为您已经在该积分中计算了它的归一化常数。您可以继续使用
      rv_continuous
      ,使用pdf的形式加上归一化常数和边界


      以下是您的代码可能是什么样子。变量
      scale
      是根据scipy文档设置的。
      norm
      是指数pdf对[0,1]的积分。只考虑了大约.49的概率质量。因此,要生成指数,当截断为[0,1]时如果区间的质量为1,我们必须用这个因子除以它的pdf

      Truncated_expon
      在文档中定义为
      rv_continuous
      的子类。通过提供其pdf,我们使scipy能够(至少对于这样一个简单的积分!)计算此分布的cdf,从而计算随机样本

      我已将cdf计算为1作为检查

      >>> from scipy import stats
      >>> lamda = 2/3
      >>> scale = 1/lamda
      >>> norm = stats.expon.cdf(1, scale=scale)
      >>> norm
      0.48658288096740798
      >>> from math import exp
      >>> class Truncated_expon(stats.rv_continuous):
      ...     def _pdf(self, x, lamda):
      ...         return lamda*exp(-lamda*x)/0.48658288096740798
      ... 
      >>> e = Truncated_expon(a=0, b=1, shapes='lamda')
      >>> e.cdf(1, lamda=lamda)
      1.0
      >>> e.rvs(size=20, lamda=lamda)
      array([ 0.20064067,  0.67646465,  0.89118679,  0.86093035,  0.14334989,
              0.10505598,  0.53488779,  0.11606106,  0.41296616,  0.33650899,
              0.95126415,  0.57481087,  0.04495104,  0.00308469,  0.23585195,
              0.00653972,  0.59400395,  0.34919065,  0.91762547,  0.40098409])
      

      按您描述的方式限定的分布通常称为“截断”分布。截断分布的属性很容易从相应的非截断分布的属性派生。实现这一点的一种方法是使用一个表示截断分布(任何类型)的类。此类的实例包含对相应的非截断分发的引用,因此您只有一个截断分发类,并根据需要将其应用于任何非截断分发。我是否也可以使用原始非截断分发的冻结rv作为stats.rv_continuous子类中的参数?这将是常规的按照Robert Dodier在其对OP的评论中建议的思路进行调整。当我试图将冻结的rv作为
      cdf()
      的参数时,我得到:
      …File”/usr/lib/python3.6/site packages/scipy/stats/_distn_infrastructure.py“,第872行,在_argcheck;cond=logical_和(cond,(asarray(arg)>0));TypeError:“>”在“rv_freezed”和“int”的实例之间不受支持。
      请将此作为新问题发布。如果您在此处给我留言,我愿意查看。