按一列分组,并根据月份获得值的总和

时间:2018-12-04 11:11:55

标签: python pandas

我有一个pandas数据框,其中包含项目和它们在特定日期的数量。例如。

date         Item     qty
2016-01-04    Rice     3
2016-01-04    Ball     3
2016-01-10    Rice     5
2016-02-02    Coffee  10
2016-02-06    Rice     3
 .....         ...    ..

数据为2年,从2016年到2018年5月。

我想知道从2016年1月到2018年5月,每个月每个商品的销售额是多少。并为其绘制线形图(x轴-月份,y-产品数量)

为此,我想到了以这种格式创建数据框:

Date    Rice   Coffee   Ball
Jan 16   8       0       3
Feb 16   10      17      5
 ....    ...    ...      ...
May 18   11      9       12

如何获取这种格式的数据?

我认为的一个选择是   df.groupby([df.date.dt.year.rename('year'),df.date.dt.month.rename('month')]).agg({'qty':np.sum}).reset_index()

但是它不起作用,是否有更好的方法来获取上述格式的结果,或者有任何更好的方法来存储结果,以便于绘制?

3 个答案:

答案 0 :(得分:1)

Series.dt.strftime用于自定义format of datetimes并汇总sum

df = df.groupby([df.date.dt.strftime('%b %y'), 'Item'])['qty'].sum().unstack(fill_value=0)

如果日期时间顺序很重要,请使用ordered categoricals

df = df.sort_values('date')
dates = df.date.dt.strftime('%b %y')
dates = pd.Categorical(dates, ordered=True, categories=dates.unique())
df1 = df.groupby([dates, 'Item'])['qty'].sum().unstack(fill_value=0)

reindex

df = df.sort_values('date')
dates = df.date.dt.strftime('%b %y')
df1 = df.groupby([dates, 'Item'])['qty'].sum().unstack(fill_value=0).reindex(dates.unique())

print (df1)
Item    Ball  Coffee  Rice
Jan 16     3       0     8
Feb 16     0      10     3

最后的DataFrame.plot.bar情节:

df1.plot.bar()

答案 1 :(得分:1)

我想你想要这样

df= df.groupby([(df.index.year),(df.index.month),'Item']).sum().unstack(fill_value=0)
df.columns=df.columns.droplevel()
df.plot(kind='bar')
plt.show()

O / P enter image description here

答案 2 :(得分:1)

给予

>>> df
        date    Item  qty
0 2016-01-04    Rice    3
1 2016-01-04    Ball    3
2 2016-01-10    Rice    5
3 2016-02-02  Coffee   10
4 2016-02-06    Rice    3

>>> df.dtypes
date    datetime64[ns]
Item            object
qty              int64
dtype: object

你可以做

>>> from pandas.tseries.offsets import MonthEnd
>>> offset = MonthEnd()
>>> 
>>> df.set_index('date').groupby([offset.rollforward, 'Item']).sum().unstack(fill_value=0)
            qty            
Item       Ball Coffee Rice
2016-01-31    3      0    8
2016-02-29    0     10    3

我会像这样保留索引,因为其中有可用的日期。如果您确实必须将它们转换为'Jan 16'之类的字符串,则可以执行以下操作:

>>> result = df.set_index('date').groupby([offset.rollforward, 'Item']).sum().unstack(fill_value=0)
>>> result.index = result.index.map(lambda d: d.strftime('%b %y'))
>>> result
        qty            
Item   Ball Coffee Rice
Jan 16    3      0    8
Feb 16    0     10    3