使用Pandas绘制重尾数据的直方图
我经常处理的数据有一个很长的“尾巴”。我想画直方图来总结这些数据的分布情况,但每次用pandas的时候,结果都是一个巨大的可见柱子,其他的柱子都看不见。
这是我正在处理的一个数据系列。因为数据很长,我用了value_counts(),这样可以在这个页面上显示。
In [10]: data.value_counts.sort_index()
Out[10]:
0 8012
25 3710
100 10794
200 11718
300 2489
500 7631
600 34
700 115
1000 3099
1200 1766
1600 63
2000 1538
2200 41
2500 208
2700 2138
5000 515
5500 201
8800 10
10000 10
10900 465
13000 9
16200 74
20000 518
21500 65
27000 64
53000 82
56000 1
106000 35
530000 3
我猜答案可能是把那些不常见的结果合并成更大的组,比如把53000、56000、106000和53000都归到一个大于50000的组里等等。同时,还需要把y轴的数值改成出现的百分比,而不是绝对数量。不过,我不太明白怎么才能自动做到这一点。
2 个回答
0
通常,重尾分布的尾部是呈现幂律的,比如帕累托分布。在这种情况下,使用对数-对数图来表示数据会非常有效。这在python中实现起来也很简单,可以参考以下链接:
需要注意的是,去掉一些数值可能不是查看幂律分布的有效方法。
你也可以考虑对你的数据进行帕累托分析
。如果你对幂律分布感兴趣,可以了解一下分类数据本质上是幂律分布的原因,因为这些数据无法被排序,这是1959年维托德·贝列维奇的研究结果。
6
df2 = df[df.value <= 5000]
df2.hist(bins=np.linspace(0,5000,101))
plt.savefig('hist1')
将数据以柱状图的形式展示:
import pandas as pd
from matplotlib import pyplot as plt
import numpy as np
mydict = {0: 8012,25: 3710,100: 10794,200: 11718,300: 2489,500: 7631,600: 34,700: 115,1000: 3099,1200: 1766,1600: 63,2000: 1538,2200: 41,2500: 208,2700: 2138,5000: 515,5500: 201,8800: 10,10000: 10,10900: 465,13000: 9,16200: 74,20000: 518,21500: 65,27000: 64,53000: 82,56000: 1,106000: 35,530000: 3}
mylist = []
for key in mydict:
for e in range(mydict[key]):
mylist.insert(0,key)
df = pd.DataFrame(mylist,columns=['value'])
df2 = df[df.value <= 5000]
作为直方图(只考虑5000及以下的值,这部分数据占了97%以上): 我喜欢用linspace来控制数据的分组。
fig = df.value.value_counts().sort_index().plot(kind="bar")
plt.savefig("figure.png")
编辑:把np.linspace(0,5000,100)
改成了np.linspace(0,5000,101)
,并更新了直方图。