根据百分位数绘制直方图

Posted

技术标签:

【中文标题】根据百分位数绘制直方图【英文标题】:Plot a histogram, based on percentiles 【发布时间】:2019-10-02 13:50:42 【问题描述】:

我有一个结构如下的框架:

df = pd.DataFrame('ID': np.random.randint(1, 13, size=1000),
                   'VALUE': np.random.randint(0, 300, size=1000))

我如何绘制图表,X 轴上会有百分位数(10%、20%、..90%) 在 Y 轴上应该有值的数量,位于百分位刻度之间,例如 20%-30% 每个 ID 都必须有一个单独的图(以及不同的百分位数)

我找到了百分位数并卡住了 q = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8] df.groupby('ID')['VALUE'].quantile(q)

我猜该图应该看起来像 VALUE 参数的直方图,但 X 轴上的百分比而不是数值

【问题讨论】:

【参考方案1】:
q = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]

for name, group in df.groupby('ID'):  # Groupy by ID column
    _, bins = pd.qcut(group.VALUE, q, retbins=True, grid=False)  # Splits data in defined quantiles
    plt.figure()
    group.VALUE.hist(bins=bins)  # Plots histogram of data with specified bins
    ax.set_xticks(q, [f'str(x) * 100%' for x in q])  # format ticks (NOT TESTED)   
    plt.show()

这里没有捕获输出图,因为它们很多。它会生成您想要的绘图,但您还需要调整刻度和格式。

要实现标准化绘图,y 轴范围为 0-100%,您需要在绘图前标准化数据(可能类似于 group.VALUE.count() / df.VALUE.count()

【讨论】:

给我一个 ValueError: Bin 边缘必须是唯一的:array([ 7.1, 8., .....]) 嗯,用你提供的样本数据测试过,无法重现 我猜这是因为在我的真实数据中的某些组中可能存在非常少量的值。我想不到 10 个【参考方案2】:

试试:

df['Quantile'] = pd.qcut(df.VALUE, q=np.arange(0,1.1,0.1))
tmp_df = df.pivot_table(index='Quantile', columns='ID', aggfunc='count')
tmp_df.plot(kind='bar', subplots=True, figsize=(10,10))
plt.show()

输出,每个子图是每个 ID 的分位数。

【讨论】:

什么是分位数?在每个 ID 中,每个百分位数都必须有单独的值 因此,困难在于按 ID 分组 - 当我尝试对其中任何一个进行 qcut 时 - 我得到一个 ValueError “Bin 边缘必须是唯一的”,因为某些组中的值很少跨度> 查看您的垃圾箱,也许是bins = sorted(list(set(bins)))。另一个语句没有问题,它将在分组上显示为Nan,在绘图上显示为0 @Quang Hoang...不错!!

以上是关于根据百分位数绘制直方图的主要内容,如果未能解决你的问题,请参考以下文章

seaborn可视化displot绘制直方图(histogram)并通过axvline函数在直方图中添加中位数(median)竖线(自定义中位数竖线的线条形式)

频率分布直方图

创建使用百分比而不是计数的 matplotlib 或 seaborn 直方图?

根据 Matplotlib 中的预计数数据绘制直方图

根据“计数”列绘制直方图连续颜色?

使用 gt 表绘制每行的直方图 - R