如何在Pandas中按动物、动作对拆堆多索引数据计算rolling mean?
按动物分组计算动作耗时的3天滚动均值(切换动物时重置)
问题背景
现有如下CSV数据,记录了不同动物每天各动作的耗时:
Animal,Day,Action,Seconds dog,1,eat,10 dog,1,play,20 dog,1,drink,30 cat,1,eat,18 cat,1,play,28 cat,1,drink,21 rabbit,1,eat,34 rabbit,1,play,19 rabbit,1,drink,29 dog,2,eat,20 dog,2,play,20 dog,2,drink,10 cat,2,eat,28 cat,2,play,38 cat,2,drink,31 rabbit,2,eat,24 rabbit,2,play,34 rabbit,2,drink,30 dog,3,eat,30 dog,3,play,20 dog,3,drink,26 cat,3,eat,11 cat,3,play,22 cat,3,drink,32 rabbit,3,eat,50 rabbit,3,play,20 rabbit,3,drink,10
需求是:使用Pandas按动物、动作分别计算Seconds的3天滚动均值,且切换动物时滚动计算自动重置(不同动物的数据不混合计算)。
尝试的代码如下,但滚动计算未在动物切换时重置:
df = pd.read_csv('data.csv') x = df.set_index(['Animal', 'Day', 'Action']).unstack('Action') x['rolling_eat'] = x[('Seconds', 'eat')].rolling(window=3, min_periods=1).mean() print(x)
问题原因
原代码直接对整列执行rolling计算,没有按Animal分组。Pandas的rolling默认是对整个序列连续计算,不会识别索引中的分组信息,导致不同动物的数据被混入同一个滚动窗口。
解决方案
通过groupby('Animal')将数据按动物分组,再对每个分组单独执行滚动计算,这样切换动物时窗口会自动重置。
完整代码
import pandas as pd df = pd.read_csv('data.csv') # 构建多级索引,将Action列展开为横向列 x = df.set_index(['Animal', 'Day', 'Action']).unstack('Action') # 按动物分组,对每个动作的耗时列计算3天滚动均值(min_periods=1确保第一天有值) x['rolling_eat'] = x[('Seconds', 'eat')].groupby('Animal').rolling(window=3, min_periods=1).mean().droplevel(0) x['rolling_drink'] = x[('Seconds', 'drink')].groupby('Animal').rolling(window=3, min_periods=1).mean().droplevel(0) x['rolling_play'] = x[('Seconds', 'play')].groupby('Animal').rolling(window=3, min_periods=1).mean().droplevel(0) # 格式化输出(保留1位小数,匹配示例格式) print(x.round(1))
关键说明
- 分组计算:
groupby('Animal')确保每个动物的滚动计算独立进行,切换动物时窗口自动重置。 droplevel(0):分组后结果会多一层Animal索引,用该方法去掉多余层级,保证与原数据索引匹配。min_periods=1:允许窗口中最少有1个数据点,确保第一天的滚动均值就是当天的数值。
输出示例(部分)
Seconds rolling_eat rolling_drink rolling_play Action drink eat play Animal Day dog 1 30.0 10.0 20.0 10.0 30.0 20.0 2 10.0 20.0 20.0 15.0 20.0 20.0 3 26.0 30.0 20.0 20.0 22.0 20.0 cat 1 21.0 18.0 28.0 18.0 21.0 28.0 2 31.0 28.0 38.0 23.0 26.0 33.0 3 32.0 11.0 22.0 19.0 28.0 29.3 rabbit 1 29.0 34.0 19.0 34.0 29.0 19.0 2 30.0 24.0 34.0 29.0 29.5 26.5 3 10.0 50.0 20.0 36.0 23.0 24.3
内容的提问来源于stack exchange,提问作者kaqqao
相关产品推荐
相关产品推荐

