如何绘制许多不均匀分布的 value_counts

2024-01-05

假设我有以下数据:

s2 = pd.Series([1,2,3,4,5,2,3,333,2,123,434,1,2,3,1,11,11,432,3,2,4,3,3,3,54,34,24,2,223,2535334,3,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,30000, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2])
s2.value_counts(normalize=True).plot()

我想表明,少数数字构成了大多数情况。问题是这将在图表的最左侧看到,然后所有其他类别都会有一个短条。

在真实数据中,x 轴将进行分类,大约有 18000 个类别,其中 4% 的计数将在 10000 左右,然后其余的将下降并在 50 左右。

更新:参见@unutbu 回答

更新了代码,我收到一个错误qcut当尝试使用元组时。

TypeError: unsupported operand type(s) for -: 'tuple' and 'tuple'

df = pd.DataFrame({'s1':[1,0,1,0], 's2':[1,0,1,1], 's3':[1,0,1,1], 's4':[0,0,0,1]})
perms = df.apply(tuple, axis=1)
prob = perms.value_counts(normalize=True).reset_index(drop='True')
category_classes = pd.qcut(prob, q=[0, .25, 0.95, 1.], 
                 labels=['bottom 25%', 'mid 70%', 'top 5%'])
prob_groups = prob.groupby(category_classes).sum()
prob_groups.plot(kind='bar')
plt.xticks(rotation=0)
plt.show()

您可以将标准化值计数保持在一定值以上threshold。然后将下面的值相加threshold并将它们归为一类,可以称为“其他”。

通过选择threshold足够高,您将能够显示对整体概率分布最重要的贡献者,同时仍然在标记为“其他”的栏中显示尾部的大小:

import matplotlib.pyplot as plt
import pandas as pd

s2 = pd.Series([1,2,3,4,5,2,3,333,2,123,434,1,2,3,1,11,11,432,3,2,4,3,3,3,54,34,24,2,223,2535334,3,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,30000, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2])
prob = s2.value_counts(normalize=True)
threshold = 0.02
mask = prob > threshold
tail_prob = prob.loc[~mask].sum()
prob = prob.loc[mask]
prob['other'] = tail_prob
prob.plot(kind='bar', rot=25)
plt.show()

您可以在条形图上合理显示的类别标签数量是有限的。对于正常大小的图表来说,3000 太多了。此外,期望观众从阅读 3000 个标签中收集到任何意义可能是不合理的。

图表应该总结数据。最主要的一点似乎是4%或5%的类别构成了绝大多数案例。所以为了让大家明白这一点,也许可以使用pd.qcut https://pandas.pydata.org/docs/reference/api/pandas.qcut.html将案例分为简单的类别,例如bottom 25%, mid 70%, and top 5%:

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

N = 18000
categories = np.arange(N)
np.random.shuffle(categories)
M = int(N*0.04)
prob = pd.Series(np.concatenate([np.random.randint(9000, 11000, size=M),
                      np.random.randint(0, 100, size=N-M), ]), index=categories)
prob /= prob.sum()
category_classes = pd.qcut(prob, q=[0, .25, 0.95, 1.], 
                 labels=['bottom 25%', 'mid 70%', 'top 5%'])
prob_groups = prob.groupby(category_classes).sum()
prob_groups.plot(kind='bar', rot=0)
plt.show()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何绘制许多不均匀分布的 value_counts 的相关文章

随机推荐