【Python】pandas窗口函数
-
移动窗口函数rolling()
- pandas.DataFrame.rolling()
- pandas.Series.rolling()
rolling(window, min_periods=None, center=False, win_type=None, on=None, axis=0, closed=None, method='single')
-
window: 滑动窗口的大小,针对索引是日期的可以使用offset类型
-
min_peirods: 窗口中需要的最小观测值数量,否则,结果为np.nan,如果window类型是offset,默认是1,否则跟滑动窗口大小一样
-
center: 是否以当前行为中心,像前后滚动划分窗口
-
on: 不统计的行,只能是string
-
axis: 轴,index(0) 或者 columns(1)
-
closed: 哪一个点排除计算 a. right 如不填写默认是该值 b. left c. both d. neither
这里理解为滑动窗口,根据每一行数据的位置来确定
-
扩展窗口函数expanding()
- pandas.DataFrame.expanding()
- pandas.Series.expanding()
expanding(min_periods=1, center=None, axis=0, method='single')
可以理解为从开始到当前行,参数说明参考rolling部分
-
指数加权移动ewm()
-
pandas.DataFrame.ewm()
-
pandas.Series.ewm()
很少使用所以,暂时先不写
-
上述的意思是对于DataFrame对象和Sesies对象都可以调用对应的rolling(),expanding(),ewm()方法
构造数据
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randn(30,4),
index=pd.date_range('2022-02-22', periods=30),
columns=['Col1','Col2','Col3','Col4'])
案例
设定窗口大小
采用默认的滚动方式,如果窗口中存在None值那么结果是NaN
df.rolling(3).max()
df.expanding(3).max()
调整窗口滚动方式
当前行在窗口中的中间位置
df.rolling(3, center=True).max()
df.expanding(3, center=True).max()
FutureWarning: The
center
argument onexpanding
will be removed in the future. 未来版本中该参数就会移除
排除指定列
df.rolling(window=3,on='Col1').max()
选择指定列
df.rolling(window=3,on='Col1')[['Col2','Col3']].max()
排除的列也会跟随
df.rolling(window=3)[['Col2','Col3']].max()
以列为滚动方向
df.rolling(window=3, axis='columns', center=True).max()
图示类比行滚动
常用函数
如果可以理解窗口大小的概念,那么就可以针对特定的需求进行处理
函数名称 | 备注 | rolling | expanding |
---|---|---|---|
count | 非空值数 | ✅ | ✅ |
sum | 求和 | ✅ | ✅ |
mean | 平均数 | ✅ | ✅ |
median | 中值 | ✅ | ✅ |
var | 方差 | ✅ | ✅ |
std | 标准差 | ✅ | ✅ |
min | 最小 | ✅ | ✅ |
max | 最大 | ✅ | ✅ |
corr([other, pairwise, ddof]) | 关联 | ✅ | ✅ |
cov([other, pairwise, ddof]) | 协方差 | ✅ | ✅ |
skew | 样本偏斜度 | ✅ | ✅ |
kurt | 峰度样本 | ✅ | ✅ |
apply(func[, raw, engine, ...]) | ✅ | ✅ | |
aggregate(func, *args, **kwargs) | ✅ | ✅ | |
quantile | 四分位数 | ✅ | ✅ |
sem | 计算平均数的滚动标准误差 | ✅ | ✅ |
rank | 排序 | ✅ | ✅ |
apply
可以使用自定义的函数
df.rolling(window=3).apply(lambda x: x.mean() + 1)
aggregate
对于每一个列指定一种算法,可以使用该函数,使用map会非常方便
df.rolling(window=3).agg({'Col1':'mean',
'Col2':lambda x: x.max(),
'Col3':np.mean})
如果传入的类型是个列表,那么对于可以计算的每一列,都进行计算
df.rolling(window=3).agg(['mean', np.max, lambda x: x.min])
总结
该部分的内容,可以类比于,SQL中的分析函数,window的大小可以使用
expanding
类比于over (partition by paritionCol order by orderByCol rows between unbounded preceding and current row)
Pandas的窗口函数中没有对应的OrderBy子句。rolling
中指定的window
大小对应的是rows between n preceding and current row
,如果修改了Center
的值为True
,那么就是rows between n/2 preceding and n/2 following
,具体情况还是要看具体需要