当前位置:首页 > 体育

histogram 5种方法教你用Python玩转histogram直方图

作者|小雨

知乎| https://zhuanlan.zhihu.com/pypcfx

简介|中途转行的数据挖掘工程师

直方图是一种可以快速展示数据概率分布的工具,直观易懂,深受数据爱好者的喜爱。平时可能会看到matplotlib、seaborn等最高级的打包库包,类似于下面的图。

这个博主会总结所有使用Python绘制直方图的方法,大致可以分为三类(详细划分为五类,参考文末总结):

纯Python实现直方图,不使用任何第三方库使用Numpy来创建直方图总结数据使用matplotlib,pandas,seaborn绘制直方图

下面,我们将逐一介绍每种方法的来龙去脉。

直方图在纯Python中的实现

在准备用纯Python绘制直方图时,最简单的想法是显示每个值在报表中出现的次数。在这种情况下,使用字典来完成这个任务是非常合适的。让我们看看下面的代码是如何实现的。

>。>。>。a = ( 0,1,1,1,2,3,7,7,23)

>。>。>。defcount_elements(seq)->格言:

..." " "从“序列”中计数元素。"""

...hist = {}

...fori inseq:

...hist[i] = hist.get(i,0) + 1

...returnhist

>。>。>。counted = count_elements(a)

>。>。>。计算

{ 0: 1, 1: 3, 2: 1, 3: 1, 7: 2, 23: 1}

我们可以看到count_elements()返回一个字典,字典中出现的键都是目标列表中唯一的值,值是所有值出现的频率。用hist[i] = hist.get(i,0)+1,累加每个值的次数,每次加1。

实际上,这个功能可以通过Python标准库,即集合来完成。计数器类,兼容Pyhont字典,覆盖字典的。update()方法。

>。>。>。从集合导入计数器

>。>。>。计数=计数器(a)

>。>。>。详细叙述

计数器({ 0: 1,1: 3,3: 1,2: 1,7: 2,23: 1})

我们可以看到这种方法的结果和之前自己实现的方法是一样的,也可以通过集合来检查两种方法得到的结果是否相等。柜台

>。>。>。counted.items() == counted.items()

真正的

我们用上面的函数重新创建了一个轮子ASCII _直方图,最后通过Python的输出格式format实现了直方图的显示。代码如下:

defascii _直方图(seq)->无:

" " "水平频率表/直方图。"""

counted = count_elements(seq)

叉入(计数):

打印(' {0:5d} {1} '。格式(k,'+'* counted[k])

该函数以数值的顺序绘制,数值出现的次数用(+)表示。在字典中调用sorted()会按顺序返回一个键列表,然后就可以得到对应的counted[k]的个数。

>。>。>。随机导入

>。>。>。random.seed( 1)

>。>。>。val =[1,3,4,6,8,9,10]

>。>。>。# `vals中的数字将出现5到15次

>。>。>。freq = (random.randint( 5,15)for _ in val)

>。>。>。数据= []

>。>。>。对于f,v in (freq,val):

...data.extend([v] * f)

>。>。>。ascii _直方图(数据)

1+++++++

3++++++++++++++

4++++++

6+++++++++

8++++++

9++++++++++++

10++++++++++++

在该代码中,val中的值不重复,每个值的出现频率由我们定义,并在5到15之间随机选择。然后,使用上面封装的函数,得到纯Python版本的直方图显示。

总结:纯python实现频率表(非标准直方图),可以通过集合直接实现。计数器方法。

用Numpy实现直方图

以上是一个使用纯Python的简单直方图,但是从数学角度来说,直方图是一个从盒子到频率的映射,可以用来估计变量的概率密度函数。但是,上面的纯Python实现版本只是一个简单的频率统计,并不是真正的直方图。

因此,我们继续从上面实现的简单直方图升级。一个真实的直方图首先要把变量划分成区域(框),也就是划分成不同的区间,然后统计每个区间的观测值个数。恰好Numpy的直方图法可以做到这一点,不仅如此,也是后面要提到的matplotlib和熊猫使用的基础。

比如看一组从拉普拉斯分布中提取的浮点样本数据。该分布比标准正态分布具有更宽的尾部,并且具有两个描述性参数(位置和规模):

>。>。>。将numpy导入为np

>。>。>。np.random.seed( 444)

>。>。>。np.set_printoptions(精度= 3)

>。>。>。d = np.random .拉普拉斯(loc= 15,scale= 3,size= 500)

>。>。>。d[ :5]

数组([ 18.406,18.087,16.004,16.221,7.358])

因为这是一个连续分布,不可能把每一个单个浮点值(也就是所有无数个小数位)都标注好(因为点太多)。但是你可以把数据分成盒子,然后统计每个盒子里观测值的个数,这才是真正的直方图应该做的。

我们来看看如何使用Numpy实现直方图频率统计。

>。>。>。hist,bin_edges = np .直方图(d)

>。>。>。嘘

数组([ 1,0,3,4,4,10,13,9,2,4])

>。>。>。bin_edges

数组([ 3.217,5.199,7.181,9.163,11.145,13.127,15.109,17.091,

19.073, 21.055, 23.037])

这个结果可能不是很直观。比方说,np .直方图()默认使用10个大小相同的区间(方框),然后返回一个元组(频率,方框边界),如上图所示。需要注意的是,这个边界的数量比盒子的数量多一个,可以简单的用下面的代码来确认。

>。>。>。hist.size,bin_edges.size

(10, 11)

这就是问题所在。Numpy如何划分盒子?简单的np .直方图()就可以做到,但是我们还是不知道怎么实现。我们来解剖一下np .直方图()的内部,看看它是如何实现的(以上面提到的列表A为例)。

>。>。>。#取a的最小值和最大值。

>。>。>。first_edge,last_edge = a.min(),a.max()

>。>。>。N _ equal _ bins =默认设置10 # numpy,10盒

>。>。>。bin _ edges = NP . Lin space(start = first _ edge,stop=last_edge,

...num = n _ equal _ bins,端点=真)

...

>。>。>。bin_edges

数组([ 0。, 2.3, 4.6, 6.9, 9.2, 11.5, 13.8, 16.1, 18.4, 20.7, 23.])

解释:首先获取一个列表的最小值和最大值,然后设置默认的框数,最后使用Numpy的linspace方法进行数据分段。分箱的结果也与实际情况吻合较好。0到23等分10份,23/10,所以每份的宽度是2.3。

除了np .直方图,还有两种方法可以实现同样的功能:np.bincount()和np.searchsorted()。我们来看看代码和对比结果。

>。>。>。bcounts = np.bincount(a)

>。>。>。hist,_= np .直方图(a,range=( 0,a.max()),bin = a . max()+1)

>。>。>。np.array_equal(hist,bcounts)

真正的

>。>。>。#正在复制`集合.计数器'

>。>。>。dict((np.unique(a),bcounts[bcounts .非零()]))

{ 0: 1, 1: 3, 2: 1, 3: 1, 7: 2, 23: 1}

综上所述,直方图可以用Numpy来实现,可以直接用np .直方图()或者np.bincount()来实现。

用Matplotlib和熊猫可视化直方图

从上面的研究中,我们看到了如何使用Python的基本工具构建直方图。让我们看看如何使用更强大的Python库包来完成直方图。Matplotlib基于Numpy直方图进行了多样化封装,提供了更加完善的可视化功能。

importmatplotlib.pyplot asplt

# matplotlib . axes . axes . hist()方法的接口

n,bin,patches = plt.hist(x=d,bins = ' auto ',color= '#0504aa ',

α= 0.7,rwidth= 0.85)

plt.grid(轴= 'y ',α= 0.75)

plt.xlabel('值')

“频率”

《我自己的直方图》

plt.text( 23,45,r'$mu=15,b=3$ ')

maxfreq = n.max()

#设置y轴的上限

PLT . ylim(ymax = NP . ceil(max freq/10)* 10 ifmax freq % 10 else maxfreq+10)

之前我们定义了X轴上的分格边界和Y轴上对应的频率。不难发现我们都是手动定义盒子数量的。但是,在上面的高级方法中,我们可以通过设置bins = ' auto '来自动选择两个编写的算法中的最佳算法,并最终计算出最合适的bin数。这里,该算法的目的是选择适当的间隔(框)宽度,并生成最能代表数据的直方图。

如果使用Python的科学计算工具,可以使用熊猫的Series .直方图()并通过matplotlib.pyplot.hist()绘制输入Series的直方图,如下代码所示。

进口熊猫aspd

尺寸,比例= 1000,10

通勤= pd。系列(np.random.gamma(比例,大小=大小)** 1.5)

通勤。绘图。历史(网格=真,箱= 20,rwidth= 0.9,

color= '#607c8e ')

PLT . title(' 1000名通勤者的通勤时间')

plt.xlabel('计数')

plt.ylabel(“通勤时间”)

plt.grid(轴= 'y ',α= 0.75)

熊猫。DataFrame .直方图()的使用方式与Series相同,但会生成DataFrame数据中每一列的直方图。

综上,我们可以用Seris.plot.hist(),DataFrame.plot.hist(),matplotlib可以用matplotlib.pyplot.hist()实现直方图。

绘制核密度估计(KDE)

KDE(核密度估计)是指核密度估计。用于估计随机变量的概率密度函数,可以使数据更加平滑。

如果使用熊猫库,可以使用plot.kde()创建内核密度图。plot.kde()同时适用于Series和DataFrame数据结构。但首先我们老公做了两个不同的数据样本做对比(两个完全分布的样本):

>。>。>。#两个精确分布的样本

>。>。>。平均值= 10,20

>。>。>。stdevs = 4,2

>。>。>。dist = pd。数据帧(

...np.random.normal(loc=means,scale=stdevs,size=( 1000,2)),

...列=[ 'a ',' b'])

>。>。>。dist.agg([ 'min ',' max ',' mean ',' std'])。四舍五入(小数= 2)

最小值- 1.5712.46

最大25.3226.44

平均值10.1219.94

标准3.941.94

如上所述,我们生成了两组正态分布样本,并通过一些描述性统计参数对两组数据进行了简单的比较。现在,我们可以在同一个Matplotlib轴上绘制每个直方图及其对应的kde。使用熊猫的plot.kde()的好处是会自动显示所有列的直方图和kde,非常方便使用。具体代码如下:

图,ax = plt .支线剧情()

dist.plot.kde(ax=ax,图例= False,title= '直方图:A对B ')

密度=真,轴=轴

ax.set_ylabel('概率')

ax.grid(轴= 'y ')

ax.set_facecolor( '#d8dcd6 ')

综上,我们可以用Seris.plot.kde(),DataFrame.plot.kde()通过熊猫实现kde图。

使用西伯恩的完美替代品

更高级的可视化工具是Seaborn,这是一个基于matplotlib的强大工具。对于直方图,Seaborn有distplot()方法,可以同时绘制单变量分布和kde的直方图,使用非常方便。以下是实现代码(以上面生成的D为例):

importseaborn assns

sns.set_style( 'darkgrid ')

sns.distplot(d)

默认情况下,distplot方法将绘制kde,并提供拟合参数,可以根据数据的实际情况选择特殊的分布。

sns.distplot(d,fit=stats .拉普拉斯,kde= False)

注意两个数字的细微差别。第一种情况,你在估计一个未知的概率密度函数(PDF),第二种情况,你知道分布,想知道哪些参数更能描述数据。

总结:要通过seaborn实现直方图,可以使用seaborn.distplot(),而seaborn也有单独的kde绘图,seaborn.kde()。

熊猫里的其他工具

除了绘图工具,熊猫还提供了方便。value_counts()方法,用于计算非空值的直方图,并将其转换为熊猫的系列结构。示例如下:

>。>。>。将熊猫作为pd导入

>。>。>。data = NP . random . choice(NP . arange(10),size= 10000,

...p=np.linspace( 1,11,10) / 60)

>。>。>。s = pd。系列(数据)

>。>。>。s.value_counts()

91831

81624

71423

61323

51089

4888

3770

2535

1347

0170

dtype:int64

>。>。>。s.value_counts(normalize=True)。head()

90.1831

80.1624

70.1423

60.1323

50.1089

dtype:float64

另外,熊猫. cut()也是强行宁滨数据的便捷方法。比如我们有一些人的年龄数据,我们想把这些数据按年龄组分类。例子如下:

>。>。>。ages = pd。系列(

...[ 1, 1, 3, 5, 8, 10, 12, 15, 18, 18, 19, 20, 25, 30, 40, 51, 52])

>。>。>。bin =(0,10,13,18,21,np.inf) #边界

>。>。>。标签=(“儿童”、“青春期前”、“青少年”、“军龄”、“成人”)

>。>。>。group = PD . cut(age,bins = bins,labels=labels)

>。>。>。groups.value _ counts()

儿童6

成人5

青少年3

军事_年龄2

青春期前1

dtype:int64

>。>。>。pd.concat((年龄,组),axis= 1)。重命名(列={ 0:'年龄',1:'组' })

年龄层

01儿童

11个孩子

23儿童

35儿童

48儿童

510儿童

612混凝土

715teen

818teen

918teen

1019军事年龄

1120军事年龄

1225成人

1330成人

1440成人

1551模块

1652模块

除了使用方便之外,更好的是这些操作最后都是用Cython代码来完成的,运行速度也很快。

总结:其他实现直方图的方法都可以。value_counts()和熊猫. cut()。

应该用哪种方法?

到目前为止,我们已经学习了许多实现直方图的方法。但是他们的缺点是什么?如何选择他们?当然,没有一种方法可以解决所有问题,也需要根据实际情况考虑如何选择。以下是在某些情况下使用的方法的建议,仅供参考。

你的情况

推荐使用

注意

列表、元组或集合的数据结构中有明确的整数数据,您不想引入任何第三方库

标准库Collection.counter()提供了一种快速直接的频率实现方法

这只是一个频率表,并没有真正意义上的直方图的方块划分

大数组数据,而你只想计算包含方框的直方图(没有可视化,纯数学计算)

Numpy的np .直方图()和np.bincount()对于直方图的纯数学计算很有帮助

有关更多信息,请参见np.digitize()

数据存在于熊猫的系列和数据帧对象中

熊猫方法,如Series.plot.hist(),DataFrame.plot.hist(),Series.value_counts(),and cut(),Series.plot.kde()和DataFrame.plot.kde()

参考熊猫的可视化部分

从任何数据结构创建高度定制和可调的直方图

推荐使用基于np .直方图()的Pyplot.hist()函数,使用频率高,容易理解。

Matplotlib可以自定义

高级包装的设计和集成(非定制)

Seaborn的distplot()可以方便地将直方图和KDE图结合起来

高级包装

参考:https://realpython.com/python-histograms/

1.《histogram 5种方法教你用Python玩转histogram直方图》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。

2.《histogram 5种方法教你用Python玩转histogram直方图》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。

3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/tiyu/1030261.html

上一篇

saya事件被打孕妇发声 saya已受到相应处罚

下一篇

发改委:海南自贸港不会冲击香港 究竟发生了什么?

大熊猫宝宝和饲养员吵架全过程 这意味着什么?

“嗯~”,“啊!”,熊猫宝宝和饲养员吵架全过程被曝光啦!果然小仙女就是可以为所欲为~快来和观观一起云吸滚滚吧!...

黄瓜怎么种植方法 露地黄瓜种植技术介绍_如何种植露地黄瓜

黄瓜怎么种植方法 露地黄瓜种植技术介绍_如何种植露地黄瓜

露地栽培黄瓜的季节因各地的气候条件而异。黄瓜酥脆可口,营养丰富,所以也成了“美容蔬菜”。露地怎么种黄瓜?今天,在学习了边肖之后,我将给你详细介绍一下露地黄瓜种植技术。  露地黄瓜种植技术背景 黑龙江、吉林、内蒙古、辽宁、山西、河北、陕西西北部等地为寒冷或高寒地区,无霜期短,一年130-180...

中国旅加大熊猫面临断粮 还原事发经过及背后真相!

众所周知,大熊猫是世界自然基金会的形象大使,是世界生物多样性保护的旗舰物种。所以,今天有一则新闻,中国大队熊猫面临食物短缺,引起了网友的广泛关注。具体是什么情况?我们来看看。据《卫报》报道,加拿大卡尔加里动物园警告说,由于...

大熊猫星二逃离哥本哈根动物园 到底是什么状况?

大熊猫星二逃离哥本哈根动物园 到底是什么状况?

据英国《每日邮报》和纽约每日新闻网8日报道,当地时间8日上午,丹麦哥本哈根动物园的大熊猫“星儿”从其豪华的熊猫馆中逃出。在公园逛了没多久,被工作人员发现并注射了镇静剂,然后安全返回熊猫馆。根据动物园内部的监控录像,星儿先是...

汤圆酱锁屏 汤圆酱锁屏主题壁纸怎么下载 抖音汤圆酱锁屏主题壁纸下载方法介绍_游侠网

汤圆酱锁屏 汤圆酱锁屏主题壁纸怎么下载 抖音汤圆酱锁屏主题壁纸下载方法介绍_游侠网

如何下载汤圆酱锁屏主题壁纸?最近颤音上有一个主题壁纸,很流行。很多朋友也想要这个主题壁纸。我们来看看下载方法。  饺子酱锁屏主题壁纸怎么下载 1.通过自己的主题商店购买 在安卓手机自带的主题商店应用中,作者已经把这个主题上架了,名字叫“加油”。目前边肖已经在小米主题店搜索过了,大家应该也在其...

男生皮肤变白的方法 【男士护肤】皮肤很黑,如何变白?

“一白遮三丑” 生活在追求美的时代,专注于男士护肤, 我们是BOSSDUN。波士顿先生从不缺席。 亲爱的男同学们: 你一直想拥有最大价值吗? 亲爱的男同学们: 你还在为如何克服皮肤问题而困惑吗? 亲爱的男同学们: 要不要在如今这个看脸的社会里争取更多立足之地?  文佳文本/编辑...

运营商断小区信号 还惊动当地信息数据中心和警方

接线员切断手机信号是怎么回事?从10月6日开始,皮都区李阳阳小区内外的手机信号突然减弱甚至消失,尤其是中国移动。本来因为小区手机信号弱,国庆期间有业主反对运营商在小区设置信号设备,惊动了当地信息数据中心和警方。 三天后,电...

9种论证方法 【干货】语文阅读理解答题技巧及解题规律大全

  • 9种论证方法 【干货】语文阅读理解答题技巧及解题规律大全
  • 9种论证方法 【干货】语文阅读理解答题技巧及解题规律大全
  • 9种论证方法 【干货】语文阅读理解答题技巧及解题规律大全