首先,我们先来认识一下直方图,按照约定俗成。以下是维基百科对直方图的定义:分布的图形表示是二维统计图表。它的两个坐标分别是统计样本和样本对应的某个属性的测量值,具体用柱状图的形式表示。因为直方图的长度和宽度很适合表示量的变化,所以更容易解释差异较小的值。直方图也是用条形标注的,而条形图和直方图就像孪生兄弟一样让很多人都搞不清楚,那么我们先来区分一下这两种图形:条形图是用条形的长度表示每个类别出现的频率,而宽度(表示类别)是固定的,没有实际的数值意义。直方图用面积表示各组的频数,条的长度表示各组的频率或频数,条的宽度表示各组的组距,所以条的长宽在直方图都是实际的数值意义。条形图描述分类变量,直方图描述数值变量。由于分组数据的连续性,直方图的矩形通常是连续排列的,而条形图的条形是分开排列的。如果单纯的文字不够直观,我们来一张图感受一下:画个直方图,区分柱状图和直方图,然后就可以安心探索直方图了。假设我们有一组数据,是某学校200名学生的身高数据。如果想知道全校学生的身高分布情况,那么直方图再合适不过了。这里我用随机数生成200个150到180之间的数来表示身高信息:data=np.random.randint(150,180,200)数据输出的结果:array([162,166,158,166,165,170,157,156,164,161,154,176,166,176,153,169,164,153,171,175,171,173,155,165,168,160,162,150,151,169,166,152,174,176,160,155,158,152,159,179,179,168,178,166,174,171,167,166,165,163,164,153,153,153,162,167,169,155,155,175,161,151,173,154,151,151,166,168,167,173,166,164,175,172,163,175,154,169,160,174,163,167,156,154,157,169,160,176,150,154,158,167,164,153,152,165,165,160,167,161,164,177,177,159,161,171,169,150,165,156,156,155,165,164,179,164,179,155,172,151,178,171,164,165,161,166,170,175,163,163,179,175,173,150,171,150,178,175,152,176,168,150,172,166,176,170,174,174,152,158,171,165,167,152,163,167,164,151,174,169,169,166,167,168,179,160,179,156,168,168,172,175,160,165,160,161,164,179,158,176,175,154,167,159,153,169,151,158,163,169,155,165,178,151,168,164,169,177,150,169])以上是200个同学的身高信息,如果常用的话存入数组看分布,直方图很容易画出来。这里我们通过这组数据来探究直方图函数中各个参数的作用,从而更容易的绘制出符合需求的直方图。bins参数bins参数是指将数据分成几组。它接收的参数可以是整数、序列或字符串。通常使用整数和序列。如果是整数n,则表示要把所有的数据分成n组进行绘制。如果是序列,就是指定每组的临界值,通过代码看差异:fig=plt.figure(figsize=(16,4))pic1=fig.add_subplot(131)plt.hist(data)plt.title("binsdefault10")pic2=fig.add_subplot(132)plt.hist(data,bins=15)plt.title("bins=15")pic3=fig.add_subplot(133)plt.hist(data,bins=[150,153,156,159,162,165,168,171,174,179])plt.title("bins的值是一个序列");可见即使是同一个数据集,分组情况不同,呈现的分布也是不同的,所以怎么分到几组也是学的。如果传递的参数是一个序列,表示标出每组的临界值。缺点是比较麻烦。优点是非常灵活,可以独立确定各组的组距。每个组的组距离可以是不同的。如果分成5组,记住要求的临界值为6,参数序列中必须有6个值。范围参数一般是对整个数据集绘制直方图。有时可能会有这样的需求。比如我要看学校里155cm到175cm之间的身高分布,那么就需要把整个数据集中起来。选择符合要求的高度绘制直方图。其实大可不必这么麻烦。可以使用range参数来解决。此参数指定绘图时使用的数据范围。它接收一个元组,并在元组中放入两个数值表示要取数据的范围。fig=plt.figure(figsize=(9,4))pic1=fig.add_subplot(121)plt.hist(data,bins=10)plt.title('rangedefaultNone')pic2=fig.add_subplot(122)plt.hist(data,bins=10,range=(155,175))#设置范围从155-175plt.title('range=(155,175)');可以看到x轴的取值范围发生了变化,整个直方图的形状也发生了变化。密度参数这个参数的含义其实很直观。参数名直译成中文就是密度。正常直方图的y轴表示频率,y轴可以通过密度参数转换为密度刻度。该参数接受一个布尔值,默认为None。fig=plt.figure(figsize=(9,4))pic1=fig.add_subplot(121)plt.hist(data,bins=10)#y轴表示计数plt.title('densitydefaultNone')pic2=fig.add_subplot(122)plt.hist(data,bins=10,density=True)#density=True将原来的y轴计数转换为概率密度计数,直方图下方的面积为1plt.title('density=True');虽然两张图的形状完全一样,但是细看可以发现y轴的值是不一样的。具体的参数作用已经在代码中以备注的形式标注出来了。这里涉及到另一个参数normed。此参数已被弃用。其作用与密度相同。只有密度就足够了。权重参数大家都很熟悉。它通常似乎表示重量。没错,这里也就是设置权重的意思。它接收一个包含值的序列。值的个数与原始数据集中的元素个数相同,即每个值都有自己单独的权重。我用随机数生成200个值作为权重。给出参数,看看不设置权重时会发生什么。x0=np.random.rand(200)#生成200个和为1的数,设随机权重比=1/sum(x0)x1=x0*ratiofig=plt.figure(figsize=(9,4))pic1=fig.add_subplot(121)plt.hist(data,bins=10)plt.title('weightsdefaultNone')pic2=fig.add_subplot(122)plt.hist(data,bins=10,weights=x1)plt.title('setweights');当所有元素的权重都一样的时候,就是第一张图的情况,但是设置权重之后,分布发生了变化,y轴也发生了变化,就是不再是简单的计数。在实际工作中,应谨慎使用权重以满足业务需求。cumulativeparameter如果英文比较好的人一眼就能看出这个参数的作用,直译成中文就是累积的意思。这里还有一个小问题。很多人愚蠢地混淆了“积累”和“积累”。其实两者还是很容易区分的。看下图就很直观了:你能直观区分“Cumulative”和“cumulative”吗?那么继续探索cumulative参数。该参数接受一个布尔值,默认为False。下面通过代码看看不同参数设置的结果是什么。fig=plt.figure(figsize=(9,4))pic1=fig.add_subplot(121)plt.hist(data,bins=10)plt.title('累积默认为假')pic2=fig.add_subplot(122)plt.hist(data,bins=10,cumulative=True)#累积直方图,显示累积分布plt.title('cumulative=True');左边是正常直方图,右边是累积直方图,也可以根据实际业务需要设置参数。限于篇幅,直方图功能的介绍先到此结束。细心的朋友可能已经发现,参数引入的顺序是按照函数官方文档中的参数顺序的,没错,就是这个顺序。但是parameters中的第一个参数x没有引入。这个参数有什么好介绍的吗?当然不是,这个参数还有一些小细节需要注意,具体的解释会在下一篇文章中和其他参数一起介绍。
