Python 箱型图的绘制并提取特征值

Python 箱型图的绘制并提取特征值,第1张

文章目录
  • 一、简介
  • 二、绘制与提取
    • 1、图形绘制
    • 2、ax.boxplot 函数的使用
    • 3、特征值提取

参考:
https://blog.csdn.net/qq_41080850/article/details/83829045
https://blog.csdn.net/aijiudu/article/details/89387328
python绘制箱线图boxplot():https://blog.csdn.net/weixin_44052055/article/details/121442449

一、简介

如下灰色框里的就是箱形图(英文:Box plot):又称为盒须图、盒式图、盒状图或箱线图,是一种用作显示一组数据分散情况资料的统计图。因型状如箱子而得名。

箱形图最大的优点就是不受异常值的影响,可以以一种相对稳定的方式描述数据的离散分布情况。

五数概括法:即用下面的五个数来概括数据(最小值;第1四分位数(Q1);中位数(Q2);第3四分位数(Q3);最大值),箱形图与之类似。


箱型图的特点:

  • 箱线图判断异常值的标准以四分位数和四分位距为基础,四分位数具有一定的耐抗性,多达25%的数据可以变得任意远而不会很大地扰动四分位数,所以异常值不会影响箱形图的数据形状,箱线图识别异常值的结果比较客观。由此可见,箱线图在识别异常值方面有一定的优越性。
  • 对于标准正态分布的样本,只有极少值为异常值。异常值越多说明尾部越重,自由度越小(即自由变动的量的个数);而偏态表示偏离程度,异常值集中在较小值一侧,则分布呈左偏态;异常值集中在较大值一侧,则分布呈右偏态。
  • 同一数轴上,几批数据的箱线图并行排列,几批数据的中位数、尾长、异常值、分布区间等形状信息便昭然若揭。所以箱型图有助于比较几批数据形状。
  • 局限:不能精确地衡量数据分布的偏态和尾重程度;对于批量比较大的数据,反映的信息更加模糊以及用中位数代表总体评价水平有一定的局限性。
二、绘制与提取

python 中已经提供了很多种箱型图的绘制方法,为我们使用者带来了极大的便利,可用的方法有

  • 方法1:利用pandas包中的Series.plot()DataFrame.plot()DataFrame.boxplot()方法;
  • 方法2:利用seaborn包中的cataplot()或者boxplot(),其中seaborn.boxplot()seaborn.cataplot()的参数kind='box'时的一种情况;
  • 方法3:利用matplotlib包中axes对象的boxplot()方法。

这么多种方法,具体的使用可以参看:https://blog.csdn.net/qq_41080850/article/details/83829045,这里只贴两个个人感觉比较简洁的。

1、图形绘制
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
 
data = [1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000, 2100]
 
df = pd.DataFrame(data)
df.plot.box(title="Box figure")
plt.show()

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
 
data = [1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000, 2100]

fig,ax=plt.subplots(figsize=(6, 6), dpi=100, facecolor='w')
ax.boxplot(data,sym='rd',positions=[2])
plt.show()


我更倾向于后者,下面详细研究一下函数的参数

2、ax.boxplot 函数的使用

(发现有人已经做了,拿来轮子直接用)

https://blog.csdn.net/weixin_44052055/article/details/121442449

上面的博客,对这个函数的参数介绍非常详细,常用的参数下面列一下:

参数含义
x指定要绘制箱线图的数据,可以是一组数据也可以是多组数据;
notch是否以凹口的形式展现箱线图,默认非凹口;
sym指定异常点的形状,默认为蓝色的+号显示;
vert是否需要将箱线图垂直摆放,默认垂直摆放;
whis指定上下须与上下四分位的距离,默认为1.5倍的四分位差;
positions指定箱线图的位置,默认为range(1, N+1),N为箱线图的数量;
widths指定箱线图的宽度,默认为0.5;
patch_artist是否填充箱体的颜色,默认为False;
meanline是否用线的形式表示均值,默认用点来表示;
showmeans是否显示均值,默认不显示;
showcaps是否显示箱线图顶端和末端的两条线,默认显示;
showbox是否显示箱线图的箱体,默认显示;
showfliers是否显示异常值,默认显示;
boxprops设置箱体的属性,如边框色,填充色等;
labels为箱线图添加标签,类似于图例的作用;
flierprops设置异常值的属性,如异常点的形状、大小、填充色等;
medianprops设置中位数的属性,如线的类型、粗细等;
meanprops设置均值的属性,如点的大小、颜色等;
capprops设置箱线图顶端和末端线条的属性,如颜色、粗细等;
whiskerprops设置须的属性,如颜色、粗细、线的类型等;
manage_ticks是否自适应标签位置,默认为True;
autorange是否自动调整范围,默认为False;

可以看到,这个函数也可以绘制多个箱型图,下面是笔者常用的设置:

	pos1=list(range(1,10))
    wid1=2;wid2=1
    tmp=ax.boxplot(datagroup,sym='rd',showmeans=True,meanline=False,
    positions=pos1,
    medianprops={'color': 'blue','linewidth': str(wid1)},   # medium setting
    flierprops={"marker": "o", "markerfacecolor": "red", "markersize": 2},  # error points
    #meanprops={'color': 'blue', 'ls': '--', 'linewidth': str(wid)},
    meanprops={"marker": "^", "markerfacecolor": "green", "markersize": 12},# mean setting
    capprops={'linewidth': str(wid2)},      # caps
    boxprops={'linewidth': str(wid1)},      # box
    whiskerprops={'linewidth': str(wid2)},  # whisker
    )
3、特征值提取

绘图很简单,但是我得到图形后并不能确切的知道这些箱型图的特征值(均值、中位数等),怎么才能得到这些值呢?首先找了一下,发现有个前辈写了个函数可以满足这一需要

https://www.cnblogs.com/wangxiaobei2019/p/11719453.html

def BoxFeature(input_list):
    """
    get the feature of box figure.
    
    > @param[in] input_list:    the series
    return: 
    < @param[out] out_list:     the feature value
    < @param[out_note]:         [ave,min,Q1,Q2,Q3,max,error_number]
    """
    percentile = np.percentile(input_list, (25, 50, 75), interpolation='linear')
    Q1 = percentile[0]  # upper quartile
    Q2 = percentile[1]
    Q3 = percentile[2]  # lower quartile
    IQR = Q3 - Q1       # Interquartile range
    ulim = Q3 + 1.5*IQR # upper limit
    llim = Q1 - 1.5*IQR # lower limit
    # llim = 0 if llim < 0 else llim
    # out_list = [llim,Q1,Q2,Q3,ulim]
    # ------- count the number of anomalies ----------
    right_list = []     # normal data
    Error_Point_num = 0
    value_total = 0
    average_num = 0
    for item in input_list:
        if item < llim or item > ulim:
            Error_Point_num += 1
        else:
            right_list.append(item)
            value_total += item
            average_num += 1
    average_value =  value_total/average_num
    out_list = [average_value,min(right_list), Q1, Q2, Q3, max(right_list), Error_Point_num]
    return out_list

后来,笔者对ax.boxplot函数的返回值进行了详细研究发现可以从它的返回值得到我想要的东西

ave = tmp['means'][0]._y  
med = np.mean(tmp['medians'][0]._y)
min_value = tmp['caps'][2*i]._y[0]
Q1 = tmp['boxes'][0]._y[0]
Q3 = tmp['boxes'][0]._y[3]
max_value = tmp['caps'][2*i+1]._y[0]
error_num = len(tmp['fliers'][0]._y)

值得注意的是,上面的小函数和根据画图函数返回结果得到的特征值有些微差别(均值),不过影响不大。至此,大功告成!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/943145.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-18
下一篇 2022-05-18

发表评论

登录后才能评论

评论列表(0条)

保存