使用Pandas绘制重尾数据的直方图

4 投票
2 回答
8932 浏览
提问于 2025-04-18 17:21

我经常处理的数据有一个很长的“尾巴”。我想画直方图来总结这些数据的分布情况,但每次用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]

bar

作为直方图(只考虑5000及以下的值,这部分数据占了97%以上): 我喜欢用linspace来控制数据的分组。

fig = df.value.value_counts().sort_index().plot(kind="bar")
plt.savefig("figure.png")

enter image description here

编辑:把np.linspace(0,5000,100)改成了np.linspace(0,5000,101),并更新了直方图。

撰写回答