61 python statistics numpy matplotlib scipy
如何在Python中的matplotlib中绘制数组数组的经验CDF?我正在寻找pylab的"hist"函数的cdf模拟.
我能想到的一件事是:
from scipy.stats import cumfreq
a = array([...]) # my array of numbers
num_bins = 20
b = cumfreq(a, num_bins)
plt.plot(b)
Run Code Online (Sandbox Code Playgroud)
这是正确的吗?有更简单/更好的方法吗?
谢谢.
Dav*_*ave 87
如果您喜欢linspace
并喜欢单行,您可以:
plt.plot(np.sort(a), np.linspace(0, 1, len(a), endpoint=False))
Run Code Online (Sandbox Code Playgroud)
鉴于我的口味,我几乎总是这样做:
# a is the data array
x = np.sort(a)
y = np.arange(len(x))/float(len(x))
plt.plot(x, y)
Run Code Online (Sandbox Code Playgroud)
即使有>O(1e6)
数据值,这对我有用.如果你真的需要减样我会设置
x = np.sort(a)[::down_sampling_step]
Run Code Online (Sandbox Code Playgroud)
编辑以回复评论/编辑我使用的原因endpoint=False
或y
上面定义的内容.以下是一些技术细节.
经验CDF通常被正式定义为
CDF(x) = "number of samples <= x"/"number of samples"
Run Code Online (Sandbox Code Playgroud)
为了完全匹配这个正式的定义,你需要使用,y = np.arange(1,len(x)+1)/float(len(x))
以便我们得到
y = [1/N, 2/N ... 1]
.这个估计器是一个无偏估计器,它将在无限样本的限制下收敛到真正的CDF 维基百科参考..
我倾向于使用y = [0, 1/N, 2/N ... (N-1)/N]
,因为(一)更容易代码/更多idomatic,(B),但仍是形式上合理的,因为人们总是可以交换CDF(x)
与1-CDF(x)
在收敛性证明,以及(c)可与上面描述的(容易)采样方法.
在某些特定情况下,定义是有用的
y = (arange(len(x))+0.5)/len(x)
Run Code Online (Sandbox Code Playgroud)
这是两个公约之间的中间人.实际上,它说"有1/(2N)
可能的值低于我在样本中看到的最低值,并且1/(2N)
值的可能性大于我迄今为止看到的最大值.
然而,对于大样本,合理分布,在回答主体给出的约定是容易写,是真正的CDF的无偏估计,并与下采样方法的工作原理.
ars*_*ars 70
您可以使用ECDF
从功能scikits.statsmodels库:
import numpy as np
import scikits.statsmodels as sm
import matplotlib.pyplot as plt
sample = np.random.uniform(0, 1, 50)
ecdf = sm.tools.ECDF(sample)
x = np.linspace(min(sample), max(sample))
y = ecdf(x)
plt.step(x, y)
Run Code Online (Sandbox Code Playgroud)
版本0.4 scicits.statsmodels
被重命名为statsmodels
.ECDF
现在位于distributions
模块中(statsmodels.tools.tools.ECDF
折旧时).
import numpy as np
import statsmodels.api as sm # recommended import according to the docs
import matplotlib.pyplot as plt
sample = np.random.uniform(0, 1, 50)
ecdf = sm.distributions.ECDF(sample)
x = np.linspace(min(sample), max(sample))
y = ecdf(x)
plt.step(x, y)
plt.show()
Run Code Online (Sandbox Code Playgroud)
AFo*_*lia 17
这看起来(几乎)正是你想要的.两件事情:
首先,结果是四项的元组.第三是箱子的大小.第二个是最小仓的起点.第一个是每个箱子中或下方的点数.(最后一个是超出限制的点数,但由于您没有设置任何点,所有点都将被分箱.)
其次,您需要重新调整结果,使最终值为1,以遵循CDF的惯例,但是否则是正确的.
这是它在幕后的作用:
def cumfreq(a, numbins=10, defaultreallimits=None):
# docstring omitted
h,l,b,e = histogram(a,numbins,defaultreallimits)
cumhist = np.cumsum(h*1, axis=0)
return cumhist,l,b,e
Run Code Online (Sandbox Code Playgroud)
它进行直方图,然后产生每个箱中计数的累积和.所以结果的第i个值是小于或等于第i个bin的最大值的数组值的数量.因此,最终值只是初始数组的大小.
最后,要绘制它,您需要使用bin的初始值和bin大小来确定您需要的x轴值.
另一种选择是使用numpy.histogram
哪个可以进行规范化并返回bin边缘.您需要自己完成结果计数的累计总和.
a = array([...]) # your array of numbers
num_bins = 20
counts, bin_edges = numpy.histogram(a, bins=num_bins, normed=True)
cdf = numpy.cumsum(counts)
pylab.plot(bin_edges[1:], cdf)
Run Code Online (Sandbox Code Playgroud)
(bin_edges[1:]
是每个垃圾箱的上边缘.)
基于戴夫答案的单线程:
plt.plot(np.sort(arr), np.linspace(0, 1, len(arr), endpoint=False))
Run Code Online (Sandbox Code Playgroud)
编辑:hans_meine在评论中也提到了这一点.
归档时间: |
|
查看次数: |
67773 次 |
最近记录: |