python - 在 pandas 中简单应用滚动回归
问题描述
考虑这个简单的例子
import pandas as pd
import numpy as np
import statsmodels.formula.api as smf
df = pd.DataFrame({'a':[1,3,5,7,4,5,6,4,7,8,9,1,3,5,7,4,5,6,4,7,8,9],
'b':[3,5,6,2,4,6,2,5,7,1,9,5,3,2,5,4,3,6,4,1,1,9]})
我正在尝试对a
on执行滚动回归b
。我正在尝试使用可用的最简单的熊猫工具:apply
. 我想使用 apply 因为我想保持返回任何回归参数的灵活性。
但是,下面的简单代码不起作用
df.rolling(10).apply(lambda x: smf.ols('a ~ b', data = x).fit())
File "<string>", line 1, in <module>
PatsyError: Error evaluating factor: NameError: name 'b' is not defined
a ~ b
^
问题是什么?谢谢!
解决方案
rolling apply
不能同时与多个列交互,也不能产生非数字值。相反,我们需要利用rolling
对象的可迭代特性。我们还需要自己处理 min_periods,因为可迭代的滚动对象会生成所有窗口结果,而不管其他rolling
参数如何。
然后,我们可以创建一些函数来从回归结果中生成结果中的每一行,以执行以下操作:
def process(x):
if len(x) >= 10:
reg = smf.ols('a ~ b', data=x).fit()
print(reg.params)
return [
# b from params
reg.params['b'],
# b from tvalues
reg.tvalues['b'],
# Both lower and upper b from conf_int()
*reg.conf_int().loc['b', :].tolist()
]
# Return NaN in the same dimension as the results
return [np.nan] * 4
df = df.join(
# join new DataFrame back to original
pd.DataFrame(
(process(x) for x in df.rolling(10)),
columns=['coef', 't', 'lower', 'upper']
)
)
df
:
a b coef t lower upper
0 1 3 NaN NaN NaN NaN
1 3 5 NaN NaN NaN NaN
2 5 6 NaN NaN NaN NaN
3 7 2 NaN NaN NaN NaN
4 4 4 NaN NaN NaN NaN
5 5 6 NaN NaN NaN NaN
6 6 2 NaN NaN NaN NaN
7 4 5 NaN NaN NaN NaN
8 7 7 NaN NaN NaN NaN
9 8 1 -0.216802 -0.602168 -1.047047 0.613442
10 9 9 0.042781 0.156592 -0.587217 0.672778
11 1 5 0.032086 0.097763 -0.724742 0.788913
12 3 3 0.113475 0.329006 -0.681872 0.908822
13 5 2 0.198582 0.600297 -0.564258 0.961421
14 7 5 0.203540 0.611002 -0.564646 0.971726
15 4 4 0.236599 0.686744 -0.557872 1.031069
16 5 3 0.293651 0.835945 -0.516403 1.103704
17 6 6 0.314286 0.936382 -0.459698 1.088269
18 4 4 0.276316 0.760812 -0.561191 1.113823
19 7 1 0.346491 1.028220 -0.430590 1.123572
20 8 1 -0.492424 -1.234601 -1.412181 0.427332
21 9 9 0.235075 0.879433 -0.381326 0.851476
设置:
import pandas as pd
import numpy as np
import statsmodels.formula.api as smf
df = pd.DataFrame({
'a': [1, 3, 5, 7, 4, 5, 6, 4, 7, 8, 9, 1, 3, 5, 7, 4, 5, 6, 4, 7, 8, 9],
'b': [3, 5, 6, 2, 4, 6, 2, 5, 7, 1, 9, 5, 3, 2, 5, 4, 3, 6, 4, 1, 1, 9]
})
推荐阅读
- c# - 关于 MVC 控制器与单独的 Web API 的架构,有多少项目?
- javascript - 图像在一秒钟后在图库滑块中消失
- html - 在 django 中设置自定义用户注册表单的样式
- php - 如何将 php rest api 与 reactjs 一起使用?
- c# - JSON .NET - 将当前 JSON 对象(例如 {"name":"value"})反序列化为类型 'System.Collections.Generic.List`1
- google-apps-script - 将发送日期(来自邮件)添加到电子表格中的行
- android - PagedList 使 DataSource 无效
- java - DialogFlow Google Assistant 的正确履行消息格式
- airflow - 如何通过 google-cluoud-composer 和气流 1.10 上的 kubectl 访问气流
- c# - 装配加载发生两次