【问题标题】:Pandas groupby sort within groups retaining multiple aggregates and visualize it with facetPandas groupby 在保留多个聚合的组内排序并用 facet 可视化它
【发布时间】:2021-10-20 21:23:33
【问题描述】:

我有这个示例数据集

products = ["A", "B", "C", "D"]
stores = ["store1", "store2", "store3"]
n = 30

product_list = [products[i] for i in np.random.randint(0, len(products), n)]
store_list = [stores[i] for i in np.random.randint(0, len(stores), n)]
rating_list = np.random.random(n) * 5
sales_list = np.random.random(n) * 10000

df = pd.DataFrame(
    {'store': store_list, 
     'product': product_list, 
     'sales': sales_list, 
     'rating': rating_list})

然后总结销售额

df_1=df.groupby(['store','product']).agg({'sales':['sum']})
df_1

并在维护商店的同时按最高销售额订购

df_2 = df_1.groupby(level=0, group_keys=False).apply(
                   lambda x: x.sort_values(('sales', 'sum'), ascending=False))
df_2

如何按商店分面,所以生成的可视化如下所示?

【问题讨论】:

    标签: python pandas dataframe matplotlib seaborn


    【解决方案1】:

    你应该重置最后一段的索引:

    df_2 = df_1.groupby(level=0, group_keys=False).apply(
                       lambda x: x.sort_values(('sales', 'sum'), ascending=False)).reset_index()
    

    然后你可以用seaborn.FacetGrid进行绘图:

    g = sns.FacetGrid(df_2, col = 'store')
    g.map(sns.barplot, 'product', 'sales')
    
    plt.show()
    

    【讨论】:

      【解决方案2】:
      • 可视化是关于讲述一个故事,并以清晰简洁的方式呈现数据以传达该故事。因此,更清楚的是每个图都有相同的 x 轴顺序。
        • 查看您的可视化的人应该能够快速辨别出哪个商店的哪个产品的总销售额最高,但如果每个轴的产品类别的顺序不同,这并不容易
      • 这可以通过pandas.DataFrame.plot 使用pandas.DataFrame.pivot_table 整形数据来完成。
      • 通过python 3.8.11matplotlib 3.4.2seaborn 0.11.2pandas 1.3.1 测试
      import pandas as pd
      import matplotlib.pyplot as plt
      
      # using the sample data; reshape df
      dfp = df.pivot_table(index='product', columns='store', values='sales', aggfunc='sum')
      
      # display(dfp)
      store          store1        store2        store3
      product                                          
      A         9303.543781  15323.422183  20738.561588
      B                 NaN   7549.028221           NaN
      C        13976.321362  22350.050356   9865.392344
      D         6905.455849   3183.767513   6010.941242
      
      # plot
      dfp.plot(kind='bar', subplots=True, layout=(1, 3), figsize=(8, 4), legend=False, rot=0,
               sharey=True, title='Store Sales by Product', ylabel='Total Sales')
      plt.show()
      

      • 这个演示更清晰,没有子图(删除subplots=True
        • 更清楚的是,产品 B 仅在商店 2 有销售
      dfp.plot(kind='bar', rot=0, figsize=(5, 3), title='Store Sales by Product', ylabel='Total Sales')
      plt.show()
      

      • 切换indexcolumns 的类别讲述了不同的故事
      dfp = df.pivot_table(index='store', columns='product', values='sales', aggfunc='sum')
      
      dfp.plot(kind='bar', rot=0, figsize=(5, 3), title='Product Sales by Store', ylabel='Total Sales')
      plt.show()
      

      seaborn.catplot

      • 使用.catplot 可以在没有.groupby.pivot_table 的情况下完成此操作,因为kind='bar' 有一个estimator 参数。
      • 使用col=
      import seaborn as sns
      
      sns.catplot(kind='bar', data=df, col='store', x='product', y='sales',
                  order=sorted(products), col_order=sorted(stores), estimator=sum, ci=False, height=3)
      plt.show()
      

      • 使用hue=
      • 仅供参考,此图的随机数据 (df) 与其他图不同。
      sns.catplot(kind='bar', data=df, hue='store', x='product', y='sales', height=3,
                  col_order=sorted(stores), estimator=sum, ci=False, order=sorted(products))
      plt.show()
      

      【讨论】:

        猜你喜欢
        • 2018-07-01
        • 2019-10-12
        • 2015-03-06
        • 2017-11-03
        • 1970-01-01
        • 2017-07-04
        • 1970-01-01
        • 1970-01-01
        • 2020-11-05
        相关资源
        最近更新 更多