⾸先我们先⽤随机函数编造⼀个包含1000个数值的⼀维numpy数组,如下:
// An highlighted block
rng = np.random.RandomState(seed=12345)
samples = stats.norm.rvs(size=1000, random_state=rng)
接下来我们将使⽤各种⽅法画出以上数据的累积分布图1、matplotlib.pyplot.hist()
def hist(self, x, bins=None, range=None, density=None, weights=None, cumulative=False, bottom=None, histtype='bar', align='mid', orientation='vertical', rwidth=None, log=False,
color=None, label=None, stacked=False, normed=None, **kwargs):
第⼀种⽅法,我们使⽤matplotlib图形库中的hist函数,熟悉该库的⼈应该知道这是⼀个直⽅图绘制函数,以上是从API中找到的hist函数的所有参数,我们给出⼀维数组或者列表x,使⽤hist画出该数据的直⽅图。
直⽅图有两种形式,分别是概率分布直⽅图和累积分布直⽅图(可能说的不准确- -!),可以通过参数cucumulative来调节,默认为False,画出的是PDF,那么True画出的便是CDF直⽅图。
PDF(figure1)可以观察到整个数据在横轴范围内的分布,CDF(figure2)则可以看出不同的数据分布间的差异性,也可以观察到整个数据的增长趋势和波动情况。
上图是概率分布直⽅图,纵轴代表概率,如果置参数normed=False,纵轴代表频数
如果我们要观察两种数据分布的差异,可能使⽤直⽅图就不是很直观,各种直⽅柱会相互重叠,我们只需更改直⽅图的图像类型,令histtype=‘step',就会画出⼀条曲线来(Figure3,实际上就是将直⽅柱并在⼀起,除边界外颜⾊透明),类似于累积分布曲线。这时,我们就能很好地观察到不同数据分布曲线间的差异。
2、numpy.histogram
def histogram(a, bins=10, range=None, normed=False, weights=None, density=None)
第⼆种⽅法我们使⽤numpy中画直⽅图的函数histogram,该函数不是⼀个直接的绘图函数(废话- -!过渡句,哈哈),给定⼀组数据a,它会返回两个数组hist和bin_edges,默认情况下hist是数据在各个区间上的频率,bin_edges是划分的各个区间的边界,说到这我们⼤概可以想到其实该函数算是上⼀个函数的底层函数,我们可以依据得到的这两个数组来画直⽅图,我们也可以⽤频率数组来直接画分布曲线(Figure4)
这⾥我只给出了⼀个最原始的图像,直接⽤hist数组画的,如果想要变成合格的累积分布曲线图,纵轴为概率(频率乘区间长度),横轴为区间(从bin_edges数组中取n-1个)就可以了3、stats.relfreq
def relfreq(a, numbins=10, defaultreallimits=None, weights=None)Returns-------frequency : ndarray
Binned values of relative frequency.lowerlimit : float Lower real limitbinsize : float
Width of each bin.
extrapoints : int Extra points.
第三种⽅法我们使⽤stats中的relfreq函数,该函数和第⼆种的⽅法类似,也并⾮是直接画图,⽽是返回关于直⽅图的⼀些数据,这⾥的frequency直接是概率⽽⾮频率,可以直接作为CDF图的纵轴,但是横轴需要⾃⼰计算,计算公式:
res.lowerlimit + np.linspace(0,res.binsize*res.frequency.size, res.frequency.size)
这个公式应该很好理解,我就不多说了,当然这些返回值都要依赖我们所给出的bins的数⽬。下⾯我给出⼀段代码,便是使⽤stats.relfreq画出概率分布直⽅图和累积分布曲线图。
rng = np.random.RandomState(seed=12345)
samples = stats.norm.rvs(size=1000, random_state=rng)res = stats.relfreq(samples, numbins=25)
x = res.lowerlimit + np.linspace(0, res.binsize*res.frequency.size,res.frequency.size)fig = plt.figure(figsize=(5, 4))ax = fig.add_subplot(1, 1, 1)
ax.bar(x, res.frequency, width=res.binsize)ax.set_title('Relative frequency histogram')ax.set_xlim([x.min(), x.max()])plt.show()
rng = np.random.RandomState(seed=12345)
samples = stats.norm.rvs(size=1000, random_state=rng)res = stats.relfreq(samples, numbins=25)
x = res.lowerlimit + np.linspace(0, res.binsize*res.frequency.size,res.frequency.size)y=np.cumsum(res.frequency)plt.plot(x,y)
plt.title('Figure6 累积分布直⽅图')plt.show()
以上就是本⼈整理出来的关于画cdf直⽅图和曲线的三种⽅法,整理这⽅⾯东西的初忠是在发现在进⾏数据分析的时候,概率分布直⽅图只能观察到数据⼤概的分布情况,⽽在不同的数据样本进⾏⽐较时却很难直观滴反映其差异性,通过看论⽂发现cdf可以做到这⼀点。
本⼈并不是数学专业出⾝,想要表达其意义,但有些描述和⽤词不当,⼤家借鉴就好。希望⼤家多多⽀持!
因篇幅问题不能全部显示,请点此查看更多更全内容