直方图
直方图是一个可以快速展示数据概率分布的工具,直观易于理解,并深受数据爱好者的喜爱。大家平时可能见到最多就是 matplotlib,seaborn 等高级封装的库包,类似以下这样的绘图。
本篇博主将要总结一下使用Python绘制直方图的所有方法,大致可分为三大类(详细划分是五类,参照文末总结):
纯Python实现直方图,不使用任何第三方库 使用Numpy来创建直方图总结数据 使用matplotlib,pandas,seaborn绘制直方图下面,我们来逐一介绍每种方法的来龙去脉。
纯Python实现histogram
当准备用纯Python来绘制直方图的时候,最简单的想法就是将每个值出现的次数以报告形式展示。这种情况下,使用 字典 来完成这个任务是非常合适的,我们看看下面代码是如何实现的。
>>> a = (0, 1, 1, 1, 2, 3, 7, 7, 23)>>> def count_elements(seq) -> dict:... """Tally elements from `seq`."""... hist = {}... for i in seq:... hist[i] = hist.get(i, 0) + 1... return hist>>> counted = count_elements(a)>>> counted{0: 1, 1: 3, 2: 1, 3: 1, 7: 2, 23: 1}
我们看到,count_elements()
返回了一个字典,字典里出现的键为目标列表里面的所有唯一数值,而值为所有数值出现的频率次数。hist[i] = hist.get(i, 0) + 1
实现了每个数值次数的累积,每次加一。
实际上,这个功能可以用一个Python的标准库 collection.Counter
类来完成,它兼容Pyhont 字典并覆盖了字典的 .update()
方法。
>>> from collections import Counter>>> recounted = Counter(a)>>> recountedCounter({0: 1, 1: 3, 3: 1, 2: 1, 7: 2, 23: 1})
可以看到这个方法和前面我们自己实现的方法结果是一样的,我们也可以通过 collection.Counter
来检验两种方法得到的结果是否相等。
>>> recounted.items() == counted.items()True
我们利用上面的函数重新再造一个轮子 ASCII_histogram,并最终通过Python的输出格式format来实现直方图的展示,代码如下:
def ascii_histogram(seq) -> None: """A horizontal frequency-table/histogram plot.""" counted = count_elements(seq) for k in sorted(counted): print('{0:5d} {1}'.format(k, '+' * counted[k]))
这个函数按照数值大小顺序进行绘图,数值出现次数用 (+) 符号表示。在字典上调用 sorted()
将会返回一个按键顺序排列的列表,然后就可以获取相应的次数 counted[k]
。
>>> import random>>> random.seed(1)>>> vals = [1, 3, 4, 6, 8, 9, 10]>>> # `vals` 里面的数字将会出现5到15次>>> freq = (random.randint(5, 15) for _ in vals)>>> data = []>>> for f, v in zip(freq, vals):... data.extend([v] * f)>>> ascii_histogram(data) 1 +++++++ 3 ++++++++++++++ 4 ++++++ 6 +++++++++ 8 ++++++ 9 ++++++++++++ 10 ++++++++++++
新闻热点
疑难解答