Pandas 日期移动平均线
Pandas Moving Average on Date
我有一个 df 如下所示:
为数据框添加代码:
df = pd.DataFrame({'Name':['John']*12
,'Type':[*'AABBBBAAABAB']
,'Period':['Noon','Morning']*6
,'Date':['1/1/2020']*2+['1/4/2020']*2+
['1/5/2020']*2+['1/2/2020']*2+
['1/3/2020']*2+['1/19/2020', '1/31/2020']
,'value':[1,2,7,8,9,10,3,4,5,6,5,6]}, index=range(1,13))
基本上我需要一个人(以 John 为例)价值的连续 2 天移动平均线,按类型和时期分类(人也是,但不在此 table 中)。
预期结果如最后一栏所示。
例如1。第 4 行,John 早上的 B 型,2020 年 1 月 4 日和 2020 年 1 月 3 日(第 10 行)的平均值为 (6+8)/2=7
,
并且没有 2020 年 1 月 3 日之前的 John 类型 B 的数据,因此第 10 行结果为 na
例如2。第 11 行和第 12 行,它们不是连续的日期,所以都是 na
如何使用pandas实现这个功能?我应该使用 transform
还是 rolling
?
您可以使用以下内容:
df.set_index('Date')\
.groupby(['Name','Type','Period'])['value']\
.rolling('2D', min_periods=2)\
.mean()\
.reset_index()
输出:
Name Type Period Date value
0 John A Morning 2020-01-01 NaN
1 John A Morning 2020-01-02 3.0
2 John A Noon 2020-01-01 NaN
3 John A Noon 2020-01-02 2.0
4 John A Noon 2020-01-03 4.0
5 John A Noon 2020-01-19 NaN
6 John B Morning 2020-01-04 NaN
7 John B Morning 2020-01-05 9.0
8 John B Morning 2020-01-03 8.0
9 John B Morning 2020-01-31 NaN
10 John B Noon 2020-01-04 NaN
11 John B Noon 2020-01-05 8.0
并且,一种将其合并回原始数据框的方法:
df_er = (df.set_index('Date')
.groupby(['Name','Type','Period'])['value']
.rolling('2D', min_periods=2)
.mean()
.rename('Expected Result'))
df.merge(df_er, left_on=['Name', 'Type', 'Period', 'Date'], right_index=True)
输出:
Name Type Period Date value Expected Result
1 John A Noon 2020-01-01 1 NaN
2 John A Morning 2020-01-01 2 NaN
3 John B Noon 2020-01-04 7 NaN
4 John B Morning 2020-01-04 8 NaN
5 John B Noon 2020-01-05 9 8.0
6 John B Morning 2020-01-05 10 9.0
7 John A Noon 2020-01-02 3 2.0
8 John A Morning 2020-01-02 4 3.0
9 John A Noon 2020-01-03 5 4.0
10 John B Morning 2020-01-03 6 8.0
11 John A Noon 2020-01-19 5 NaN
12 John B Morning 2020-01-31 6 NaN
我有一个 df 如下所示:
为数据框添加代码:
df = pd.DataFrame({'Name':['John']*12
,'Type':[*'AABBBBAAABAB']
,'Period':['Noon','Morning']*6
,'Date':['1/1/2020']*2+['1/4/2020']*2+
['1/5/2020']*2+['1/2/2020']*2+
['1/3/2020']*2+['1/19/2020', '1/31/2020']
,'value':[1,2,7,8,9,10,3,4,5,6,5,6]}, index=range(1,13))
基本上我需要一个人(以 John 为例)价值的连续 2 天移动平均线,按类型和时期分类(人也是,但不在此 table 中)。
预期结果如最后一栏所示。
例如1。第 4 行,John 早上的 B 型,2020 年 1 月 4 日和 2020 年 1 月 3 日(第 10 行)的平均值为 (6+8)/2=7
,
并且没有 2020 年 1 月 3 日之前的 John 类型 B 的数据,因此第 10 行结果为 na
例如2。第 11 行和第 12 行,它们不是连续的日期,所以都是 na
如何使用pandas实现这个功能?我应该使用 transform
还是 rolling
?
您可以使用以下内容:
df.set_index('Date')\
.groupby(['Name','Type','Period'])['value']\
.rolling('2D', min_periods=2)\
.mean()\
.reset_index()
输出:
Name Type Period Date value
0 John A Morning 2020-01-01 NaN
1 John A Morning 2020-01-02 3.0
2 John A Noon 2020-01-01 NaN
3 John A Noon 2020-01-02 2.0
4 John A Noon 2020-01-03 4.0
5 John A Noon 2020-01-19 NaN
6 John B Morning 2020-01-04 NaN
7 John B Morning 2020-01-05 9.0
8 John B Morning 2020-01-03 8.0
9 John B Morning 2020-01-31 NaN
10 John B Noon 2020-01-04 NaN
11 John B Noon 2020-01-05 8.0
并且,一种将其合并回原始数据框的方法:
df_er = (df.set_index('Date')
.groupby(['Name','Type','Period'])['value']
.rolling('2D', min_periods=2)
.mean()
.rename('Expected Result'))
df.merge(df_er, left_on=['Name', 'Type', 'Period', 'Date'], right_index=True)
输出:
Name Type Period Date value Expected Result
1 John A Noon 2020-01-01 1 NaN
2 John A Morning 2020-01-01 2 NaN
3 John B Noon 2020-01-04 7 NaN
4 John B Morning 2020-01-04 8 NaN
5 John B Noon 2020-01-05 9 8.0
6 John B Morning 2020-01-05 10 9.0
7 John A Noon 2020-01-02 3 2.0
8 John A Morning 2020-01-02 4 3.0
9 John A Noon 2020-01-03 5 4.0
10 John B Morning 2020-01-03 6 8.0
11 John A Noon 2020-01-19 5 NaN
12 John B Morning 2020-01-31 6 NaN