如何在 pandas 中进行前向滚动求和?
how to do forward rolling sum in pandas?
我有这个数据框:
dates = pd.date_range(start='2016-01-01', periods=20, freq='d')
df = pd.DataFrame({'A': [1] * 20 + [2] * 12 + [3] * 8,
'B': np.concatenate((dates, dates)),
'C': np.arange(40)})
我按日期对数据框进行了排序:
df.sort_values('B',inplace=True)
我希望按日期做一个前向滚动总和。但是,我只能使用以下方式进行反向滚动求和:
df.groupby('A').rolling(7, on='B',min_periods=0).C.sum()
A B
1 2016-01-01 0.0
2016-01-02 1.0
2016-01-03 3.0
2016-01-04 6.0
2016-01-05 10.0
2016-01-06 15.0
我想做前滚总和
我认为需要按 iloc[::-1]
更改顺序:
df1 = (df.iloc[::-1]
.groupby('A', sort=False)
.rolling(7, on='B',min_periods=0).C
.sum()
.iloc[::-1])
我想你想要
df["C"] = df["A"].cumsum()
查看文档 here
设置
dates = pd.date_range(start='2016-01-01', periods=20, freq='d')
df = pd.DataFrame({'A': [1] * 20 + [2] * 12 + [3] * 8,
'B': np.concatenate((dates, dates)),
'C': np.arange(40)})
按'B'
排序然后当我们滚动时,用iloc[::-1]
反向滚动
def rev_roll(x):
return x.iloc[::-1].rolling(7, min_periods=0).sum().iloc[::-1]
df.assign(Roll=df.sort_values('B').groupby('A').C.transform(rev_roll))
输出
A B C Roll
0 1 2016-01-01 0 21
1 1 2016-01-02 1 28
2 1 2016-01-03 2 35
3 1 2016-01-04 3 42
4 1 2016-01-05 4 49
5 1 2016-01-06 5 56
6 1 2016-01-07 6 63
7 1 2016-01-08 7 70
8 1 2016-01-09 8 77
9 1 2016-01-10 9 84
10 1 2016-01-11 10 91
11 1 2016-01-12 11 98
12 1 2016-01-13 12 105
13 1 2016-01-14 13 112
14 1 2016-01-15 14 99
15 1 2016-01-16 15 85
16 1 2016-01-17 16 70
17 1 2016-01-18 17 54
18 1 2016-01-19 18 37
19 1 2016-01-20 19 19
20 2 2016-01-01 20 161
21 2 2016-01-02 21 168
22 2 2016-01-03 22 175
23 2 2016-01-04 23 182
24 2 2016-01-05 24 189
25 2 2016-01-06 25 196
26 2 2016-01-07 26 171
27 2 2016-01-08 27 145
28 2 2016-01-09 28 118
29 2 2016-01-10 29 90
30 2 2016-01-11 30 61
31 2 2016-01-12 31 31
32 3 2016-01-13 32 245
33 3 2016-01-14 33 252
34 3 2016-01-15 34 219
35 3 2016-01-16 35 185
36 3 2016-01-17 36 150
37 3 2016-01-18 37 114
38 3 2016-01-19 38 77
39 3 2016-01-20 39 39
如果您的日期不是完全连续的(比如您在这里和那里缺少一两天)并且您想要固定的 N 天 window(而不是 N 条记录 window), 你可以使用:
def forward_rolling_mean(sub_df, col='units', days_ahead=7):
rolling_data = [sub_df[sub_df['date'].between(date+pd.Timedelta(days=1), date+pd.Timedelta(days=1+days_ahead-1))][col].mean() for date in sub_df['date']]
return pd.DataFrame({'%s_next%idays_mean' % (col, days_ahead): rolling_data}, index=sub_df['date'])
您也可以将其更改为 return 系列而不是数据框。稍后您可以将其加入原始数据。
简单如:
df['B'] = df['A'].rolling(3).sum().shift(-3)
我有这个数据框:
dates = pd.date_range(start='2016-01-01', periods=20, freq='d')
df = pd.DataFrame({'A': [1] * 20 + [2] * 12 + [3] * 8,
'B': np.concatenate((dates, dates)),
'C': np.arange(40)})
我按日期对数据框进行了排序:
df.sort_values('B',inplace=True)
我希望按日期做一个前向滚动总和。但是,我只能使用以下方式进行反向滚动求和:
df.groupby('A').rolling(7, on='B',min_periods=0).C.sum()
A B
1 2016-01-01 0.0
2016-01-02 1.0
2016-01-03 3.0
2016-01-04 6.0
2016-01-05 10.0
2016-01-06 15.0
我想做前滚总和
我认为需要按 iloc[::-1]
更改顺序:
df1 = (df.iloc[::-1]
.groupby('A', sort=False)
.rolling(7, on='B',min_periods=0).C
.sum()
.iloc[::-1])
我想你想要
df["C"] = df["A"].cumsum()
查看文档 here
设置
dates = pd.date_range(start='2016-01-01', periods=20, freq='d')
df = pd.DataFrame({'A': [1] * 20 + [2] * 12 + [3] * 8,
'B': np.concatenate((dates, dates)),
'C': np.arange(40)})
按'B'
排序然后当我们滚动时,用iloc[::-1]
反向滚动
def rev_roll(x):
return x.iloc[::-1].rolling(7, min_periods=0).sum().iloc[::-1]
df.assign(Roll=df.sort_values('B').groupby('A').C.transform(rev_roll))
输出
A B C Roll
0 1 2016-01-01 0 21
1 1 2016-01-02 1 28
2 1 2016-01-03 2 35
3 1 2016-01-04 3 42
4 1 2016-01-05 4 49
5 1 2016-01-06 5 56
6 1 2016-01-07 6 63
7 1 2016-01-08 7 70
8 1 2016-01-09 8 77
9 1 2016-01-10 9 84
10 1 2016-01-11 10 91
11 1 2016-01-12 11 98
12 1 2016-01-13 12 105
13 1 2016-01-14 13 112
14 1 2016-01-15 14 99
15 1 2016-01-16 15 85
16 1 2016-01-17 16 70
17 1 2016-01-18 17 54
18 1 2016-01-19 18 37
19 1 2016-01-20 19 19
20 2 2016-01-01 20 161
21 2 2016-01-02 21 168
22 2 2016-01-03 22 175
23 2 2016-01-04 23 182
24 2 2016-01-05 24 189
25 2 2016-01-06 25 196
26 2 2016-01-07 26 171
27 2 2016-01-08 27 145
28 2 2016-01-09 28 118
29 2 2016-01-10 29 90
30 2 2016-01-11 30 61
31 2 2016-01-12 31 31
32 3 2016-01-13 32 245
33 3 2016-01-14 33 252
34 3 2016-01-15 34 219
35 3 2016-01-16 35 185
36 3 2016-01-17 36 150
37 3 2016-01-18 37 114
38 3 2016-01-19 38 77
39 3 2016-01-20 39 39
如果您的日期不是完全连续的(比如您在这里和那里缺少一两天)并且您想要固定的 N 天 window(而不是 N 条记录 window), 你可以使用:
def forward_rolling_mean(sub_df, col='units', days_ahead=7):
rolling_data = [sub_df[sub_df['date'].between(date+pd.Timedelta(days=1), date+pd.Timedelta(days=1+days_ahead-1))][col].mean() for date in sub_df['date']]
return pd.DataFrame({'%s_next%idays_mean' % (col, days_ahead): rolling_data}, index=sub_df['date'])
您也可以将其更改为 return 系列而不是数据框。稍后您可以将其加入原始数据。
简单如:
df['B'] = df['A'].rolling(3).sum().shift(-3)