获取 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
我有以下形式的时间序列数据:
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