Сгруппировать по одному столбцу и получить сумму значений в виде столбцов на основе месяцев - PullRequest
0 голосов
/ 04 декабря 2018

У меня есть фрейм данных 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 года.

Я хочу знать, сколько было продано за каждый месяц в месяц, с января 2016 года по май 2018 года.И построить для него линейный график (ось х - месяцы, у - количество продуктов)

Для этого я подумал о создании кадра данных в этом формате:

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 голосов
/ 04 декабря 2018

Я думаю, что вы хотите, как это,

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

0 голосов
/ 04 декабря 2018

Учитывая

>>> 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
0 голосов
/ 04 декабря 2018

Используйте Series.dt.strftime для пользовательского формата даты и времени и совокупности 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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...