83

在执行 a 之后groupby.sum()DataFrame我在尝试创建我想要的情节时遇到了一些麻烦。

具有多索引的分组数据框

import pandas as pd
import numpy as np

np.random.seed(365)
rows = 100
data = {'Month': np.random.choice(['2014-01', '2014-02', '2014-03', '2014-04'], size=rows),
        'Code': np.random.choice(['A', 'B', 'C'], size=rows),
        'ColA': np.random.randint(5, 125, size=rows),
        'ColB': np.random.randint(0, 51, size=rows),}
df = pd.DataFrame(data)

     Month Code  ColA  ColB
0  2014-03    C    59    47
1  2014-01    A    24     9
2  2014-02    C    77    50

dfg = df.groupby(['Code', 'Month']).sum()

              ColA  ColB
Code Month              
A    2014-01   124   102
     2014-02   398   282
     2014-03   474   198
     2014-04   830   237
B    2014-01   477   300
     2014-02   591   167
     2014-03   522   192
     2014-04   367   169
C    2014-01   412   180
     2014-02   275   205
     2014-03   795   291
     2014-04   901   309

如何kind='bar'为每个创建一个子图 ( ) Code,其中 x 轴是Month,条形图是ColAColB

4

3 回答 3

130

我发现 unstack(level) 方法可以完美地工作,它的另一个好处是不需要先验知道有多少代码。

ax = dfg.unstack(level=0).plot(kind='bar', subplots=True, rot=0, figsize=(9, 7), layout=(2, 3))
plt.tight_layout()

在此处输入图像描述

于 2014-08-20T19:28:55.840 回答
25

使用以下 DataFrame ...

数据框

# using pandas version 0.14.1
from pandas import DataFrame
import pandas as pd
import matplotlib.pyplot as plt

data = {'ColB': {('A', 4): 3.0,
('C', 2): 0.0,
('B', 4): 51.0,
('B', 1): 0.0,
('C', 3): 0.0,
('B', 2): 7.0,
('Code', 'Month'): '',
('A', 3): 5.0,
('C', 1): 0.0,
('C', 4): 0.0,
('B', 3): 12.0},
'ColA': {('A', 4): 66.0,
('C', 2): 5.0,
('B', 4): 125.0,
('B', 1): 5.0,
('C', 3): 41.0,
('B', 2): 52.0,
('Code', 'Month'): '',
('A', 3): 22.0,
('C', 1): 14.0,
('C', 4): 51.0,
('B', 3): 122.0}}

df = DataFrame(data)

...您可以绘制以下内容(使用横截面):

f, a = plt.subplots(3,1)
df.xs('A').plot(kind='bar',ax=a[0])
df.xs('B').plot(kind='bar',ax=a[1])
df.xs('C').plot(kind='bar',ax=a[2])

在此处输入图像描述

一个用于 A,一个用于 B,一个用于 C,x 轴:“月”,条形为 ColA 和 ColB。也许这就是你要找的。

于 2014-08-20T09:34:00.990 回答
0
  • 创建所需的可视化就是塑造数据框以适应绘图 API。
    • seaborn可以很容易地从没有.groupbyor的数据框中聚合长格式数据.pivot_table
  • 给定原始数据框df,最简单的选择是将其转换为长格式pandas.DataFrame.melt,然后使用 绘制seaborn.catplot,这是 matplotlib 的高级 API。
    • 将默认值estimator从更改meansum
  • OP 中的'Month'列是字符串类型。一般来说,最好将列转换为 datetime dtypepd._to_datetime
  • python 3.8.11, pandas 1.3.2, matplotlib 3.4.2,中测试seaborn 0.11.2

seaborn.catplot

import seaborn as sns

dfm = df.melt(id_vars=['Month', 'Code'], var_name='Cols')

     Month Code  Cols  value
0  2014-03    C  ColA     59
1  2014-01    A  ColA     24
2  2014-02    C  ColA     77
3  2014-04    B  ColA    114
4  2014-01    C  ColA     67

# specify row and col to get a plot like that produced by the accepted answer
sns.catplot(kind='bar', data=dfm, col='Code', x='Month', y='value', row='Cols', order=sorted(dfm.Month.unique()),
            col_order=sorted(df.Code.unique()), estimator=sum, ci=None, height=3.5)

在此处输入图像描述

sns.catplot(kind='bar', data=dfm, col='Code', x='Month', y='value', hue='Cols', estimator=sum, ci=None,
            order=sorted(dfm.Month.unique()), col_order=sorted(df.Code.unique()))

在此处输入图像描述

pandas.DataFrame.plot

  • pandas使用matplotlib和默认的绘图后端。
  • 要生成像公认答案一样的图,最好使用pandas.DataFrame.pivot_table而不是.groupby,因为生成的数据框形状正确,无需取消堆叠。
dfp = df.pivot_table(index='Month', columns='Code', values=['ColA', 'ColB'], aggfunc='sum')

dfp.plot(kind='bar', subplots=True, rot=0, figsize=(9, 7), layout=(2, 3))
plt.tight_layout()

在此处输入图像描述

于 2021-09-06T23:31:46.353 回答