获取 Pandas 中每月 3 个月数据的平滑移动组的总和数据

Getting sum data for smoothly shifting groups of 3 months of a months data in Pandas

我有以下形式的时间序列数据:

  Item  2020 Jan  2020 Feb  2020 Mar  2020 Apr  2020 May  2020 Jun
0    A         0         1         2         3         4         5
1    B         5         4         3         2         1         0

这是月度数据,但我想获取此数据的季度数据。正常的季度数据将通过汇总 1 月至 3 月和 4 月至 6 月计算得出,如下所示:

  Item  2020 Q1  2020 Q2
0    A        3       12
1    B       12        3

我想获得更平滑的季度数据,以便每个新数据项仅移动 1 个月,而不是 3 个月。所以它将有 1 月至 3 月,然后是 2 月至 4 月,然后是 3 月至 5 月,然后是 4 月至 6 月。所以结果数据看起来像这样:

  Item  2020 Q1  2020 Q1  2020 Q1  2020 Q2
0    A        3        6        9       12
1    B       12        9        6        3

我认为这与 cumsum 类似,可以按如下方式使用:

df_dates = df.iloc[:,1:]
df_dates.cumsum(axis=1)

这导致以下结果:

   2020 Jan  2020 Feb  2020 Mar  2020 Apr  2020 May  2020 Jun
0         0         1         3         6        10        15
1         5         9        12        14        15        15

但它不是获取整个时间的总和,而是获取最近 3 个月(一个季度)的总和。 我不知道这个版本的 cumsum 是如何调用的,但我在很多地方看到它,所以我相信可能有一个库函数。

尝试按列分组 axis=1:

>>> df.iloc[:, [0]].join(df.iloc[:, 1:].groupby(pd.to_datetime(df.columns[1:], format='%Y %b').quarter, axis=1).sum().add_prefix('Q'))
  Item  Q1  Q2
0    A   3  12
1    B  12   3
>>> 

编辑:

我误解了你的问题,做你想做的事试试rolling总和:

>>> x = df.rolling(3, axis=1).sum().dropna(axis='columns')
>>> df.iloc[:, [0]].join(x.set_axis('Q' + pd.to_datetime(df.columns[1:], format='%Y %b').quarter.astype(str)[:len(x.T)], axis=1))
  Item    Q1   Q1   Q1    Q2
0    A   3.0  6.0  9.0  12.0
1    B  12.0  9.0  6.0   3.0
>>> 

让我们分步解决

  • 将索引设置为Item
  • 将日期类列解析为季度
  • 计算 window 大小 3
  • 的滚动总和
  • 将计算出的滚动总和沿列轴移动 2 个单位并去掉最后两列
s = df.set_index('Item')
s.columns = pd.PeriodIndex(s.columns, freq='M').strftime('%Y Q%q')

s = s.rolling(3, axis=1).sum().shift(-2, axis=1).iloc[:, :-2]

print(s)

      2020 Q1  2020 Q1  2020 Q1  2020 Q2
Item                                    
A         3.0      6.0      9.0     12.0
B        12.0      9.0      6.0      3.0