Pandas dataframe groupby 多年滚动统计
Pandas dataframe groupby multiple years rolling stat
我有一个 pandas 数据框,我试图在按列分组后为其计算扩展窗口聚合。数据结构是这样的:
df = pd.DataFrame([['A',1,2015,4],['A',1,2016,5],['A',1,2017,6],['B',1,2015,10],['B',1,2016,11],['B',1,2017,12],
['A',1,2015,24],['A',1,2016,25],['A',1,2017,26],['B',1,2015,30],['B',1,2016,31],['B',1,2017,32],
['A',2,2015,4],['A',2,2016,5],['A',2,2017,6],['B',2,2015,10],['B',2,2016,11],['B',2,2017,12]],columns=['Typ','ID','Year','dat'])\
.sort_values(by=['Typ','ID','Year'])
即
Typ ID Year dat
0 A 1 2015 4
6 A 1 2015 24
1 A 1 2016 5
7 A 1 2016 25
2 A 1 2017 6
8 A 1 2017 26
12 A 2 2015 4
13 A 2 2016 5
14 A 2 2017 6
3 B 1 2015 10
9 B 1 2015 30
4 B 1 2016 11
10 B 1 2016 31
5 B 1 2017 12
11 B 1 2017 32
15 B 2 2015 10
16 B 2 2016 11
17 B 2 2017 12
通常,每个 Type-ID
的年数和每个 Type-ID-Year
的行数完全不同。我需要按 Type
和 ID
列对这个数据框进行分组,然后按 Year
计算所有观察值的扩展窗口中位数和标准差。我想得到这样的输出结果:
Typ ID Year median std
0 A 1 2015 14.0 14.14
1 A 1 2016 14.5 11.56
2 A 1 2017 15.0 10.99
3 A 2 2015 4.0 0
4 A 2 2016 4.5 0
5 A 2 2017 5.0 0
6 B 1 2015 20.0 14.14
7 B 1 2016 20.5 11.56
8 B 1 2017 21.0 10.99
9 B 2 2015 10.0 0
10 B 2 2016 10.5 0
11 B 2 2017 11.0 0
因此,我想要类似 groupby
by ['Type','ID','Year']
的东西,每个 Type-ID-Year
的中位数和标准差是针对具有相同 Type-ID
和累积的所有数据计算的包括 Year
.
如何在不手动迭代的情况下执行此操作?
这个问题没有activity,所以我会post我找到的解决方案。
mn = df.groupby(by=['Typ','ID']).dat.expanding().median().reset_index().set_index('level_2')
mylast = lambda x: x.iloc[-1]
mn = mn.join(df['Year'])
mn = mn.groupby(by=['Typ','ID','Year']).agg(mylast).reset_index()
我的解决方案遵循这个算法:
- 对数据进行分组,计算加窗的中位数,并取回原始索引
- 返回原始索引,从原始数据框中获取年份
- 按分组列分组,为每个列取最后一个(按顺序)值
这给出了所需的输出。对于标准偏差(或任何其他所需的统计数据),可以遵循相同的过程。
我有一个 pandas 数据框,我试图在按列分组后为其计算扩展窗口聚合。数据结构是这样的:
df = pd.DataFrame([['A',1,2015,4],['A',1,2016,5],['A',1,2017,6],['B',1,2015,10],['B',1,2016,11],['B',1,2017,12],
['A',1,2015,24],['A',1,2016,25],['A',1,2017,26],['B',1,2015,30],['B',1,2016,31],['B',1,2017,32],
['A',2,2015,4],['A',2,2016,5],['A',2,2017,6],['B',2,2015,10],['B',2,2016,11],['B',2,2017,12]],columns=['Typ','ID','Year','dat'])\
.sort_values(by=['Typ','ID','Year'])
即
Typ ID Year dat
0 A 1 2015 4
6 A 1 2015 24
1 A 1 2016 5
7 A 1 2016 25
2 A 1 2017 6
8 A 1 2017 26
12 A 2 2015 4
13 A 2 2016 5
14 A 2 2017 6
3 B 1 2015 10
9 B 1 2015 30
4 B 1 2016 11
10 B 1 2016 31
5 B 1 2017 12
11 B 1 2017 32
15 B 2 2015 10
16 B 2 2016 11
17 B 2 2017 12
通常,每个 Type-ID
的年数和每个 Type-ID-Year
的行数完全不同。我需要按 Type
和 ID
列对这个数据框进行分组,然后按 Year
计算所有观察值的扩展窗口中位数和标准差。我想得到这样的输出结果:
Typ ID Year median std
0 A 1 2015 14.0 14.14
1 A 1 2016 14.5 11.56
2 A 1 2017 15.0 10.99
3 A 2 2015 4.0 0
4 A 2 2016 4.5 0
5 A 2 2017 5.0 0
6 B 1 2015 20.0 14.14
7 B 1 2016 20.5 11.56
8 B 1 2017 21.0 10.99
9 B 2 2015 10.0 0
10 B 2 2016 10.5 0
11 B 2 2017 11.0 0
因此,我想要类似 groupby
by ['Type','ID','Year']
的东西,每个 Type-ID-Year
的中位数和标准差是针对具有相同 Type-ID
和累积的所有数据计算的包括 Year
.
如何在不手动迭代的情况下执行此操作?
这个问题没有activity,所以我会post我找到的解决方案。
mn = df.groupby(by=['Typ','ID']).dat.expanding().median().reset_index().set_index('level_2')
mylast = lambda x: x.iloc[-1]
mn = mn.join(df['Year'])
mn = mn.groupby(by=['Typ','ID','Year']).agg(mylast).reset_index()
我的解决方案遵循这个算法:
- 对数据进行分组,计算加窗的中位数,并取回原始索引
- 返回原始索引,从原始数据框中获取年份
- 按分组列分组,为每个列取最后一个(按顺序)值
这给出了所需的输出。对于标准偏差(或任何其他所需的统计数据),可以遵循相同的过程。