pandas rolling实现52周周度数据滚动年度线性回归报错解决
报错原因
你触发报错的核心原因有两个:
- 直接把pandas生成的
Rolling自定义对象传给了statsmodels的ols接口作为输入数据源。Rolling对象不是结构化的DataFrame/数组格式,ols解析输入时会把它识别为不可哈希的分类数据对象,直接抛出all items must be hashable错误。 - 原代码的循环逻辑存在错位:内层遍历
year标签时没有同步切换对应时间的滚动窗口,所有回归调用都重复传入同一个未迭代的Rolling对象,既触发报错也无法得到每个年度窗口的回归结果。
另外你的代码里还有一个隐藏bug:tickers列表中写的BRK.A和数据集实际列名BRK不匹配,修正后运行会触发列不存在的报错,需要同步对齐。
修正步骤
- 先对数据集按日期升序重排,避免滚动窗口顺序错乱
- 滚动窗口设置
min_periods=52参数,自动过滤样本量不足52周的不完整窗口 - 遍历滚动对象生成每个独立窗口的DataFrame片段,将窗口和你定义的年度标签一一绑定
- 每个窗口单独作为ols的数据源传入,逐标的完成回归
修正后可运行代码
import pandas as pd import statsmodels.formula.api as smf df = pd.read_excel("dataset\Special_Proj.xlsx") df['Date'] = pd.to_datetime(df['Date'], format='%m/%d/%y') # 按日期升序排序,重置索引保证窗口顺序正确 df = df.sort_values('Date').reset_index(drop=True) def rollingwindow(): # 已将BRK.A改为和数据集列名一致的BRK tickers = ['FDX', 'BRK', 'MSFT', 'NVDA', 'INTC', 'AMD', 'JPM', 'T', 'AAPL', 'AMZN', 'GS'] year = ['Year 2', 'Year 3', 'Year 4', 'Year 5', 'Year 6', 'Year 7', 'Year 8', 'Year 9', 'Year 10', 'Year 11', 'Year 12', 'Year 13','Year 14','Year 15','Year 16','Year 17','Year 18','Year 19','Year 20' ] # 筛选目标时间段数据 target_df = df[df['Date'] >= '2000-12-29'].reset_index(drop=True) # 生成52周滚动窗口,仅保留满52周的完整窗口 rolling_windows = [win for win in target_df.rolling(window=52, min_periods=52)] # 年度标签和窗口一一对应遍历 for y, window in zip(year, rolling_windows): for t in tickers: # 传入当前窗口的DataFrame做回归 model = smf.ols(f'{t} ~ SP50', data=window).fit() print(model.summary(yname="Status", xname=['Intercept', f'{t} Beta'], title=f'Regression {y}')) print() rollingwindow()
注:如果你的数据集后续补全了BRK.A的列名,把tickers列表里的对应值改回去即可。
内容的提问来源于stack exchange,提问作者Trevor Seibert
相关产品推荐
相关产品推荐

