【问题标题】:How to plot groupby as percentage in seaborn?如何在seaborn中将groupby绘制为百分比?
【发布时间】:2019-05-15 21:53:59
【问题描述】:

我有一个二元分类问题,我想用 RandomForestClassifier 解决这个问题。我的目标列是“成功”,即 0 或 1。我想调查数据,看看它的样子。为此,我尝试按类别计算图。但这并不是说“成功”占总数的百分比是多少(即成功 == 1)

如何更改以下图,以便这些子图显示(成功 == 1)占所有帖子的百分比? (假设在工作日类别中,在“星期六”日我有 10 个数据点,其中 7 个是成功的(“成功”== 1),所以我想在当天有一个点为 0.7 的条形图。

这是实际的情节(计数:-/):

这是我的数据框的一部分:

这是用于生成实际绘图的实际代码:

# Plot 

sns.set(style="darkgrid")

x_vals = [['page_name', 'weekday'],['type', 'industry']]
subtitles = [['by Page', 'by Weekday'],['by Content Type', 'by Industry']]

fig, ax = plt.subplots(2,2, figsize=(15,10))
#jitter = [[False, 1], [0.5, 0.2]]

for j in range(len(ax)):
    for i in range(len(ax[j])):
        ax[j][i].tick_params(labelsize=15)
        ax[j][i].set_xlabel('label', fontsize=17, position=(.5,20))
        if (j == 0) :
            ax[j][i].tick_params(axis="x", rotation=50) 
        ax[j][i].set_ylabel('label', fontsize=17)
        ax[j][i] = sns.countplot(x=x_vals[j][i], hue="successful", data=mainDf, ax=ax[j][i])

for j in range(len(ax)):
    for i in range(len(ax[j])):
        ax[j][i].set_xlabel('', fontsize=17)
        ax[j][i].set_ylabel('count', fontsize=17)
        ax[j][i].set_title(subtitles[j][i], fontsize=18)

fig.suptitle('Success Count by Category', position=(.5,1.05), fontsize=20)

fig.tight_layout()
fig.show()

PS:请不要,我正在使用 Seaborn。如果可能的话,解决方案也应该使用 Seaborn。谢谢!

【问题讨论】:

    标签: python pandas matplotlib plot seaborn


    【解决方案1】:

    您可以在此处使用barplot。我不能 100% 确定您真正想要实现的目标,因此我开发了几种解决方案。

    每次成功(不成功)的成功(不成功)频率

    fig, axes = plt.subplots(2, 2, figsize=(15, 10))
    
    mainDf['frequency'] = 0 # a dummy column to refer to
    for col, ax in zip(['page_name', 'weekday', 'type', 'industry'], axes.flatten()):
        counts = mainDf.groupby([col, 'successful']).count()
        freq_per_group = counts.div(counts.groupby('successful').transform('sum')).reset_index()
        sns.barplot(x=col, y='frequency', hue='successful', data=freq_per_group, ax=ax)
    

    每组成功(不成功)的频率

    fig, axes = plt.subplots(2, 2, figsize=(15, 10))
    
    mainDf['frequency'] = 0 # a dummy column to refer to
    for col, ax in zip(['page_name', 'weekday', 'type', 'industry'], axes.flatten()):
        counts = mainDf.groupby([col, 'successful']).count()
        freq_per_group = counts.div(counts.groupby(col).transform('sum')).reset_index()
        sns.barplot(x=col, y='frequency', hue='successful', data=freq_per_group, ax=ax)
    

    根据您提供的数据,给出了

    每个总数的成功(不成功)频率

    fig, axes = plt.subplots(2, 2, figsize=(15, 10))
    
    mainDf['frequency'] = 0 # a dummy column to refer to
    total = len(mainDf)
    for col, ax in zip(['page_name', 'weekday', 'type', 'industry'], axes.flatten()):
        counts = mainDf.groupby([col, 'successful']).count()
        freq_per_total = counts.div(total).reset_index()
        sns.barplot(x=col, y='frequency', hue='successful', data=freq_per_total, ax=ax)
    

    【讨论】:

    • 非常感谢!比我需要的还要详细。只有一个情节没有奏效。 “每次成功(不成功)的频率”之一我在 sns.barplot 行收到一个错误,说:“TypeError:只有长度为 1 的数组可以转换为 Python 标量”我认为 python 不喜欢函数传递给“估计器”
    • 没错,感谢您指出这一点。请查看更新后的答案。
    • 嘿@ayorgo 是否有可能以表格方式显示这些数据?以便准确的数值可读?
    【解决方案2】:

    ax[j][i] = sns.countplot(x=x_vals[j][i], hue="successful", data=mainDf, ax=ax[j][i])这一行改为ax[j][i] = sns.barplot(x=x_vals[j][i], y='successful', data=mainDf, ax=ax[j][i], ci=None, estimator=lambda x: sum(x) / len(x) * 100)

    你的代码是

    sns.set(style="darkgrid")
    
    x_vals = [['page_name', 'weekday'],['type', 'industry']]
    subtitles = [['by Page', 'by Weekday'],['by Content Type', 'by Industry']]
    
    fig, ax = plt.subplots(2,2, figsize=(15,10))
    #jitter = [[False, 1], [0.5, 0.2]]
    
    for j in range(len(ax)):
        for i in range(len(ax[j])):
            ax[j][i].tick_params(labelsize=15)
            ax[j][i].set_xlabel('label', fontsize=17, position=(.5,20))
            if (j == 0) :
                ax[j][i].tick_params(axis="x", rotation=50) 
            ax[j][i].set_ylabel('label', fontsize=17)
            ax[j][i] = sns.barplot(x=x_vals[j][i], y='successful', data=mainDf, ax=ax[j][i], ci=None, estimator=lambda x: sum(x) / len(x) * 100)
    
    for j in range(len(ax)):
        for i in range(len(ax[j])):
            ax[j][i].set_xlabel('', fontsize=17)
            ax[j][i].set_ylabel('percent', fontsize=17)
            ax[j][i].set_title(subtitles[j][i], fontsize=18)
    
    fig.suptitle('Success Percentage by Category', position=(.5,1.05), fontsize=20)
    
    fig.tight_layout()
    fig.show()
    

    【讨论】:

      猜你喜欢
      • 2016-06-12
      • 2020-12-02
      • 1970-01-01
      • 2015-05-10
      • 1970-01-01
      • 2021-12-22
      • 1970-01-01
      • 1970-01-01
      • 2014-07-08
      相关资源
      最近更新 更多