将日期索引拆分为年度索引和月度列

Split date index to yearly index and monthly columns

我有一个像这样的 DataFrame:

data_date   value
2016-01-01  1
2016-01-02  2
2017-02-05  3
2017-02-07  4
2017-03-09  5

我需要将其转换为 table,以年为索引,以月为列。 (使用总和进行汇总)

最终输出应该是这样的

      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()

所以现在我将数据聚合到每一行作为 month/Yr。 我对如何将月份列为列并将年份列为行感到困惑。

你能帮我吗?

尝试 pivot_table:

(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

您可以使用:

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')

如果您需要一年中的所有月份,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