在Python中创建离散累积分布

3

我正在尝试在Python中创建一个累积分布,但一直收到AttributeError的错误提示。我的代码如下:

import sys
import scipy.stats
import numpy 

def CDF_Random(N,NE,E,SE,S,SW,W,NW,Iterations):
    WindDir = [0,45,90,135,180,225,270,315]
    Freq = [N,NE,E,SE,S,SW,W,NW]

    cdf=scipy.stats.rv_discrete.cdf(WindDir,Freq)  
    cdf_rand=cdf.rvs(size=Iterations)    
    return (cdf_rand)

if __name__ == '__main__':
    N = float(sys.argv[1])
    NE = float(sys.argv[2])
    E = float(sys.argv[3])
    SE = float(sys.argv[4])
    S = float(sys.argv[5])
    SW = float(sys.argv[6])
    W = float(sys.argv[7])
    NW = float(sys.argv[8])
    Iterations = float(sys.argv[9])
    numpy.set_printoptions(threshold=Iterations)
    sys.stdout.write(str(CDF_Random(N,NE,E,SE,S,SW,W,NW,Iterations)))

我得到的错误取决于我使用的WindDir和Freq值,有时它们是像上面代码中所示的数组,有时其中一个是单个整数或它们两个都是,或者其中一个可能是0到1之间的数字。

AttributeError: 'int' object has no attribute '_fix_loc'

或者

AttributeError: 'list' object has no attribute '_fix_loc'

或者

AttributeError: 'float' object has no attribute '_fix_loc'

我在谷歌搜索和这个网站上搜寻了很久,但是没有找到答案。我也花了很长时间尝试不同的输入并使用了Python网站。

编辑 我尝试的输入如下: 请注意,由于输入数组的长度不同,代码需要进行编辑。 所有这些都在命令提示符下运行。

python C:\Users\...\python\CDF.py 0.01 0.02 0.03 0.4 0.98 0.99 1 5

这会导致出现以下错误

AttributeError: 'list' object has no attribute '_fix_loc'

编辑代码后,导入sys、scipy.stats和numpy模块。

定义一个名为CDF_Random的函数。

    cdf=scipy.stats.rv_discrete.cdf(5,1)

   cdf_rand=cdf.rvs(size=Iterations)    
    return (cdf_rand)

    return (cdf)

if __name__ == '__main__':

    sys.stdout.write(str(CDF_Random()))

以下错误信息被返回:
属性错误:'int'对象没有'_fix_loc'属性
def CDF_Random():
    cdf=scipy.stats.rv_discrete.cdf(0.5,1)

   cdf_rand=cdf.rvs(size=Iterations)    
    return (cdf_rand)

    return (cdf)

if __name__ == '__main__':

    sys.stdout.write(str(CDF_Random()))

发生此错误的原因是

AttributeError: 'float' object has no attribute '_fix_loc'

我也尝试了其他的组合,例如把数组作为第一个变量,整数和浮点数作为第二个变量。

cdf=scipy.stats.rv_discrete.cdf([array],0.5)
cdf=scipy.stats.rv_discrete.cdf([array],[array])
cdf=scipy.stats.rv_discrete.cdf(4,[array])
cdf=scipy.stats.rv_discrete.cdf([array],5)

1
你在那个神奇的返回集合 return(cdf_rand); return(cdf) 中的意思是什么?Python 在第一个 return 后就离开了函数,所以你根本没有返回 cdf。不过,你可以将其作为元组或列表返回,例如 return((cdf_rand, cdf))return([cdf_rand, cdf]) - Rubens
这是一个打字错误,已经进行了编辑,谢谢。 - user2519890
请添加一个样本输入,以便他人可以运行和测试您的程序,并且能够重现您所看到的相同错误。 - Rubens
1个回答

2

scipy.stats.rv_discrete.cdf函数用于计算分布在某些列出的分位数处的概率密度。在使用该函数前,您需要先创建自己的分布。请尝试以下操作:

mydist = scipy.stats.rv_discrete(name = 'mydistribution', values=(WindDir,Freq))

注意:Freq 应该实际上是概率,并且总和应为1,因此在传递给 .rv_discrete 之前,您应该将每个成员除以 Freq 的总和。

更明确地说,此代码从使用 WindDir 和 Freq 制作的分布中返回 Iteration 个随机变量。(尽管我稍微更改了名称,因为我不喜欢在测试中使用 sysargs)。

import sys
import scipy.stats
import numpy 
import random

def CDF_Random(probs,Iterations):
    WindDir = [0,45,90,135,180,225,270,315]
    Freq = probs
    mydist = scipy.stats.rv_discrete(name = 'mydistribution', values=(WindDir,Freq))  
    cdf_rand=mydist.rvs(size=Iterations)    
    #cdf=scipy.stats.rv_discrete.cdf(cdf_rand,[.5,1,10,50,99])
    return (cdf_rand)

if __name__ == '__main__':
    probs = [random.randint(1,10) for _ in xrange(8)]
    probs = [float(p)/sum(probs) for p in probs]
    Iterations = 30
    numpy.set_printoptions(threshold=Iterations)
    a=CDF_Random(probs,Iterations)

提供:

>>> a
array([  0, 270, 180, 180,   0, 180,  45,  45, 270, 270, 270,   0,  45,
        45, 180,  45, 180, 180, 270, 225,  45, 180, 270, 315, 225,  45,
       180, 180,   0,   0])

如果您想评估分布的累积分布函数,则使用mydist.cdf([要评估的百分位数数组]) 例如:
>>> mydist.cdf([1,10,25,50,75,99])
array([ 0.1627907 ,  0.1627907 ,  0.1627907 ,  0.30232558,  0.30232558,
        0.39534884])

更详细的信息可在文档中找到。同时也可以查看您的rv_discrete实例的文档字符串,即print mydist.__doc__


谢谢 Seth,这解决了我的问题,并且关于 .cdf 的额外解释帮助我更全面地理解了函数实际上在做什么。在来这里寻求帮助之前,我已经使用了你指引我去的 scipy 网站/文档。再次感谢。 - user2519890

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接