Pandas 基于多列分组的滚动平均值
Pandas Rolling mean based on groupby multiple columns
我有一个长格式数据框,其中两列有重复值,另一列有数据。我想为每个组找到 SMA。我的问题是:rolling()
只是忽略了数据按两列分组的事实。
这是一些虚拟数据和代码。
import numpy as np
import pandas as pd
dtix=pd.Series(pd.date_range(start='1/1/2019', periods=4) )
df=pd.DataFrame({'ix1':np.repeat([0,1],4), 'ix2':pd.concat([dtix,dtix]), 'data':np.arange(0,8) })
df
ix1 ix2 data
0 0 2019-01-01 0
1 0 2019-01-02 1
2 0 2019-01-03 2
3 0 2019-01-04 3
0 1 2019-01-01 4
1 1 2019-01-02 5
2 1 2019-01-03 6
3 1 2019-01-04 7
现在,当我对这些数据执行分组滚动平均时,我得到如下输出:
df.groupby(['ix1','ix2']).agg({'data':'mean'}).rolling(2).mean()
data
ix1 ix2
0 2019-01-01 NaN
2019-01-02 0.5
2019-01-03 1.5
2019-01-04 2.5
1 2019-01-01 3.5
2019-01-02 4.5
2019-01-03 5.5
2019-01-04 6.5
期望输出:
然而,我真正想要的是:
sma
ix1 ix2
0 2019-01-01 NaN
2019-01-02 0.5
2019-01-03 1.5
2019-01-04 2.5
1 2019-01-01 NaN
2019-01-02 4.5
2019-01-03 5.5
2019-01-04 6.5
感谢您对此的帮助。
第一级 (ix1
) 使用另一个 groupby
与 rolling
:
df1 = (df.groupby(['ix1','ix2'])
.agg({'data':'mean'})
.groupby(level=0, group_keys=False)
.rolling(2)
.mean())
print (df1)
data
ix1 ix2
0 2019-01-01 NaN
2019-01-02 0.5
2019-01-03 1.5
2019-01-04 2.5
1 2019-01-01 NaN
2019-01-02 4.5
2019-01-03 5.5
2019-01-04 6.5
在您的解决方案中,聚合后返回一列 DataFrame
,因此链接 rolling
处理所有行,而不是像需要的每个组:
print(df.groupby(['ix1','ix2']).agg({'data':'mean'}))
data
ix1 ix2
0 2019-01-01 0
2019-01-02 1
2019-01-03 2
2019-01-04 3
1 2019-01-01 4
2019-01-02 5
2019-01-03 6
2019-01-04 7
我有一个长格式数据框,其中两列有重复值,另一列有数据。我想为每个组找到 SMA。我的问题是:rolling()
只是忽略了数据按两列分组的事实。
这是一些虚拟数据和代码。
import numpy as np
import pandas as pd
dtix=pd.Series(pd.date_range(start='1/1/2019', periods=4) )
df=pd.DataFrame({'ix1':np.repeat([0,1],4), 'ix2':pd.concat([dtix,dtix]), 'data':np.arange(0,8) })
df
ix1 ix2 data 0 0 2019-01-01 0 1 0 2019-01-02 1 2 0 2019-01-03 2 3 0 2019-01-04 3 0 1 2019-01-01 4 1 1 2019-01-02 5 2 1 2019-01-03 6 3 1 2019-01-04 7
现在,当我对这些数据执行分组滚动平均时,我得到如下输出:
df.groupby(['ix1','ix2']).agg({'data':'mean'}).rolling(2).mean()
data ix1 ix2 0 2019-01-01 NaN 2019-01-02 0.5 2019-01-03 1.5 2019-01-04 2.5 1 2019-01-01 3.5 2019-01-02 4.5 2019-01-03 5.5 2019-01-04 6.5
期望输出: 然而,我真正想要的是:
sma ix1 ix2 0 2019-01-01 NaN 2019-01-02 0.5 2019-01-03 1.5 2019-01-04 2.5 1 2019-01-01 NaN 2019-01-02 4.5 2019-01-03 5.5 2019-01-04 6.5
感谢您对此的帮助。
第一级 (ix1
) 使用另一个 groupby
与 rolling
:
df1 = (df.groupby(['ix1','ix2'])
.agg({'data':'mean'})
.groupby(level=0, group_keys=False)
.rolling(2)
.mean())
print (df1)
data
ix1 ix2
0 2019-01-01 NaN
2019-01-02 0.5
2019-01-03 1.5
2019-01-04 2.5
1 2019-01-01 NaN
2019-01-02 4.5
2019-01-03 5.5
2019-01-04 6.5
在您的解决方案中,聚合后返回一列 DataFrame
,因此链接 rolling
处理所有行,而不是像需要的每个组:
print(df.groupby(['ix1','ix2']).agg({'data':'mean'}))
data
ix1 ix2
0 2019-01-01 0
2019-01-02 1
2019-01-03 2
2019-01-04 3
1 2019-01-01 4
2019-01-02 5
2019-01-03 6
2019-01-04 7