【问题标题】:Pandas histogram df.hist() group byPandas 直方图 df.hist() 分组方式
【发布时间】:2018-02-03 15:12:38
【问题描述】:

如何使用 group by 绘制带有 pandas DataFrame.hist() 的直方图? 我有一个包含 5 列的数据框:“A”、“B”、“C”、“D”和“Group”

有两个组类:“yes”和“no”

使用:

df.hist() 

我得到了 4 列中每一列的历史记录。

现在我想获得相同的 4 个图表,但带有蓝条(group="yes")和红条(group="no")。

我试过这个没有成功:

df.hist(by = "group")

【问题讨论】:

    标签: pandas matplotlib histogram


    【解决方案1】:

    这不是最灵活的解决方法,但特别适用于您的问题。

    def sephist(col):
        yes = df[df['group'] == 'yes'][col]
        no = df[df['group'] == 'no'][col]
        return yes, no
    
    for num, alpha in enumerate('abcd'):
        plt.subplot(2, 2, num)
        plt.hist(sephist(alpha)[0], bins=25, alpha=0.5, label='yes', color='b')
        plt.hist(sephist(alpha)[1], bins=25, alpha=0.5, label='no', color='r')
        plt.legend(loc='upper right')
        plt.title(alpha)
    plt.tight_layout(pad=0.4, w_pad=0.5, h_pad=1.0)
    

    您可以通过以下方式使其更通用:

    • dfby 参数添加到sephist: def sephist(df, by, col)
    • 使子图循环更加灵活:for num, alpha in enumerate(df.columns)

    因为matplotlib.pyplot.hist的第一个参数可以取

    单个数组或不需要的数组序列 长度相同

    ...另一种选择是:

    for num, alpha in enumerate('abcd'):
        plt.subplot(2, 2, num)
        plt.hist((sephist(alpha)[0], sephist(alpha)[1]), bins=25, alpha=0.5, label=['yes', 'no'], color=['r', 'b'])
        plt.legend(loc='upper right')
        plt.title(alpha)
    plt.tight_layout(pad=0.4, w_pad=0.5, h_pad=1.0)
    

    【讨论】:

    • 谢谢。奇怪的是,这种可视化不包含在 pandas 方法中。
    【解决方案2】:

    使用 Seaborn

    如果您愿意使用 Seaborn,可以使用 seaborn.FacetGrid 轻松制作包含多个子图和每个子图中多个变量的图。

    import numpy as np; np.random.seed(1)
    import pandas as pd
    import seaborn as sns
    import matplotlib.pyplot as plt
    
    df = pd.DataFrame(np.random.randn(300,4), columns=list("ABCD"))
    df["group"] = np.random.choice(["yes", "no"], p=[0.32,0.68],size=300)
    
    df2 = pd.melt(df, id_vars='group', value_vars=list("ABCD"), value_name='value')
    
    bins=np.linspace(df2.value.min(), df2.value.max(), 10)
    g = sns.FacetGrid(df2, col="variable", hue="group", palette="Set1", col_wrap=2)
    g.map(plt.hist, 'value', bins=bins, ec="k")
    
    g.axes[-1].legend()
    plt.show()
    

    【讨论】:

      【解决方案3】:

      我概括了其他评论的解决方案之一。希望它可以帮助那里的人。我添加了一行以确保为每一列保留分箱(数字和范围),无论组如何。该代码应该适用于“二进制”和“分类”分组,即“by”可以指定一个列,其中有 N 个唯一组。如果要绘制的列数超过子图空间,绘图也会停止。

      import numpy as np
      import matplotlib.pyplot as plt
      
      def composite_histplot(df, columns, by, nbins=25, alpha=0.5):
          def _sephist(df, col, by):
              unique_vals = df[by].unique()
              df_by = dict()
              for uv in unique_vals:
                  df_by[uv] = df[df[by] == uv][col]
              return df_by
          subplt_c = 4
          subplt_r = 5
          fig = plt.figure()
          for num, col in enumerate(columns):
              if num + 1 > subplt_c * subplt_r:
                  continue
              plt.subplot(subplt_c, subplt_r, num+1)
              bins = np.linspace(df[col].min(), df[col].max(), nbins)
              for lbl, sepcol in _sephist(df, col, by).items():
                  plt.hist(sepcol, bins=bins, alpha=alpha, label=lbl)
                  plt.legend(loc='upper right', title=by)
                  plt.title(col)
          plt.tight_layout()
          
          return fig
      

      【讨论】:

        【解决方案4】:

        TLDR 单线;
        它不会创建子图,但会创建 4 个不同的图;

        [df.groupby('group')[i].plot(kind='hist',title=i)[0] and plt.legend() and plt.show() for i in 'ABCD']
        

        下面的完整工作示例

        import numpy as np; np.random.seed(1)
        import pandas as pd
        import seaborn as sns
        import matplotlib.pyplot as plt
        
        df = pd.DataFrame(np.random.randn(300,4), columns=list("ABCD"))
        df["group"] = np.random.choice(["yes", "no"], p=[0.32,0.68],size=300)
        
        [df.groupby('group')[i].plot(kind='hist',title=i)[0] and plt.legend() and plt.show() for i in 'ABCD']
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-05-28
          • 1970-01-01
          • 2016-02-13
          • 1970-01-01
          • 1970-01-01
          • 2013-11-04
          • 2020-11-08
          • 1970-01-01
          相关资源
          最近更新 更多