使用Python DataFrame滚动线性拟合

时间:2015-05-05 21:44:27

标签: python pandas dataframe

我想在我的数据框中执行与线性拟合的移动窗口。

n =5
df = pd.DataFrame(index=pd.date_range('1/1/2000', periods=n))
df['B'] = [1.9,2.3,4.4,5.6,7.3]
df['A'] = [3.2,1.3,5.6,9.4,10.4]

            B   A
2000-01-01  1.9 3.2
2000-01-02  2.3 1.3
2000-01-03  4.4 5.6
2000-01-04  5.6 9.4
2000-01-05  7.3 10.4

比如B列,我想使用前两行进行线性拟合,然后使用第二和第三行进行另一次线性拟合,依此类推。对于A列也是如此。我只对拟合的斜率感兴趣,所以最后,我想要一个新的数据框,上面的条目被不同的滚动斜率所取代。

完成后

df.reset_index()

我尝试像

这样的东西
model = pd.ols(y=df['A'], x=df['index'], window_type='rolling',window=3)

但是我得到了

KeyError: 'index'

编辑: 我给了一个新专栏

df['i'] = range(0,len(df))

我现在可以运行

pd.ols(y=df['A'], x=df.i, window_type='rolling',window=3)

(它给出了window = 2的错误)

我并不理解这一点,因为我期待一串数字,但我只得到一个结果

-------------------------Summary of Regression Analysis---------------     

Formula: Y ~ <x> + <intercept>

Number of Observations:         3
Number of Degrees of Freedom:   2

R-squared:         0.8981
Adj R-squared:     0.7963

Rmse:              1.1431

F-stat (1, 1):     8.8163, p-value:     0.2068

Degrees of Freedom: model 1, resid 1

-----------------------Summary of Estimated Coefficients--------------
Variable       Coef    Std Err     t-stat    p-value    CI 2.5%   CI 97.5%
--------------------------------------------------------------------------------
         x     2.4000     0.8083       2.97     0.2068     0.8158     3.9842
 intercept     1.2667     2.5131       0.50     0.7028    -3.6590     6.1923

---------------------------------摘要结束----------- ----------------------

编辑2: 现在我更清楚地知道发生了什么。我可以使用

访问拟合的不同值
model.beta

2 个答案:

答案 0 :(得分:0)

我还没有尝试过,但我认为你不需要指定window_type='rolling',如果指定窗口,窗口将自动设置为滚动。

Source.

答案 1 :(得分:0)

我使用您使用DatetimeIndex创建的pd.date_range执行此操作时遇到问题,并且由于其中的类型数量和API之间明显不兼容,因此查找日期时间是一件令人困惑的事情。如果日期是一个整数(例如自12/31/99或几年后的几天)或浮动在你的例子中,我将如何做到这一点。它不会帮助您解决日期时间问题,但希望它有助于滚动线性拟合部分。

使用整数生成日期而不是日期时间:

df = pd.DataFrame()
df['date'] = range(1,6)
df['B'] = [1.9,2.3,4.4,5.6,7.3]
df['A'] = [3.2,1.3,5.6,9.4,10.4]

   date    B     A
0     1  1.9   3.2
1     2  2.3   1.3
2     3  4.4   5.6
3     4  5.6   9.4
4     5  7.3  10.4

由于您希望每次分组2个日期,然后在每个组上拟合线性模型,让我们复制记录并使用索引为每个组编号:

df_dbl = pd.concat([df,df], names = ['date', 'B', 'A']).sort()
df_dbl = df_dbl.iloc[1:-1] # removes the first and last row

   date    B     A
0     1  1.9   3.2 # this record is removed
0     1  1.9   3.2
1     2  2.3   1.3
1     2  2.3   1.3
2     3  4.4   5.6
2     3  4.4   5.6
3     4  5.6   9.4
3     4  5.6   9.4
4     5  7.3  10.4
4     5  7.3  10.4 # this record is removed

c = df_dbl.index[1:len(df_dbl.index)].tolist()
c.append(max(df_dbl.index))
df_dbl.index = c

   date    B     A
1     1  1.9   3.2
1     2  2.3   1.3
2     2  2.3   1.3
2     3  4.4   5.6
3     3  4.4   5.6
3     4  5.6   9.4
4     4  5.6   9.4
4     5  7.3  10.4

现在它已准备好按index分组,以Bdate运行线性模型,这是我从Using Pandas groupby to calculate many slopes学到的。我使用scipy.stats.linregress,因为我使用pd.ols得到了奇怪的结果,并且无法找到好的文档来理解原因(也许是因为它面向日期时间)。

1    0.4
2    2.1
3    1.2
4    1.7