#python #pandas #datetimeindex
Вопрос:
У меня есть фрейм данных, подобный этому:
data_date value 2016-01-01 1 2016-01-02 2 2017-02-05 3 2017-02-07 4 2017-03-09 5
Мне нужно преобразовать его в таблицу с годами в качестве индекса и месяцами в качестве столбцов. (агрегировать с использованием суммы)
Конечный результат должен выглядеть следующим образом
Jan | Feb | Mar | Apr | ........... Dec | 2016 3 | xx | xx | xx | ............ | 2017 xx | 7 | 5 | xx | ............ |
Вот это то, что я сделал:
Чтобы упростить копирование:
import pandas as pd df=pd.DataFrame([ {'data_date': '2016-01-01', 'value': 1}, {'data_date': '2016-01-02', 'value': 2}, {'data_date': '2017-02-05', 'value': 3}, {'data_date': '2017-02-07', 'value': 4}, {'data_date': '2017-03-09', 'value': 5}])
Я использовал TimeGrouper, чтобы сначала объединить его в ежемесячный примерно так:
df['data_date'] = pd.to_datetime(df['data_date']) df.set_index('data_date', inplace=True) grp_df = df.groupby([pd.Grouper(freq='M')]).sum()
Итак, теперь у меня есть данные, агрегированные по каждой строке за месяц/год. Я застрял в том, как сделать месяцы столбцами, а год строкой.
Не могли бы вы помочь мне с этим, пожалуйста?
Ответ №1:
Попробуйте сводную таблицу:
(df.assign(year=df.data_date.dt.year, month=df.data_date.dt.strftime('%b')) .pivot_table(index='year', columns='month', values='value', aggfunc='sum') .reindex(['Jan','Feb','Mar','Dec'], axis=1) # change this to correct month names )
Или с pd.crosstab
:
pd.crosstab( index=df.data_date.dt.year, columns=df.data_date.dt.strftime('%b'), values=df['value'], aggfunc='sum' ).reindex(['Jan','Feb','Mar','Dec'], axis=1)
Выход:
month Jan Feb Mar Dec year 2016 3.0 NaN NaN NaN 2017 NaN 7.0 5.0 NaN
Ответ №2:
Вы можете использовать:
df['data_date'] = pd.to_datetime(df['data_date']) df['year'] = df['data_date'].dt.year df['month'] = df['data_date'].dt.month_name().str[:3] df = df.pivot_table(index='year', columns='month', values='value', aggfunc='sum')
Комментарии:
1. Спасибо за ваш ответ! Ваш метод верен , но ответ не совпал, потому что сводная таблица является агрегацией по умолчанию
mean
, но мне нужноsum
2. О, извините, я пропустил эту часть, отредактированную сейчас
Ответ №3:
Если вам нужны все месяцы года, resample
может быть полезно решение с помощью. Нет смысла делать это, если вам это не нужно :
df['data_date'] = pd.to_datetime(df['data_date']) grp = df.set_index('data_date') grp = grp.resample('M').sum().reset_index() grp = grp.assign(year = grp.data_date.dt.year, month = grp.data_date.dt.month_name().str[:3]) grp['month'] = grp['month'].astype(pd.CategoricalDtype(grp.month.unique(), ordered=True)) grp.pivot('year', 'month', 'value') month Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec year 2016 3.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 2017 0.0 7.0 5.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN