首页 > 解决方案 > 由两列组成的 Pandas 回归

问题描述

我要做什么

我想通过股票项目(例如Apple,Amazon等)以及特定日期期间(例如2月15日至3月14日)获得平均股价,回归系数和浮动股票价格的R平方。作为涵盖 30 年的量化投资模拟的一部分。问题是它太慢了。起初,我用 PostgreSQL 编写了整个代码,但它太慢了 - 2 小时后没有完成。在询问了管理信息系统的教授朋友后,我第一次尝试熊猫。


到目前为止实现的数据结构如下所示:

  1. 原始数据(名为dfStock的数据帧)
    ──────────────────────────────────────
    代码| 日期 | 日期组 | 价格 |
    ────────────────────────────────────────
    AAPL | 20200205 | 20200205 | ###.## |
    苹果 | 20200206 | 20200305 | ###.## |
    ...
    AAPL | 20200305 | 20200305 | ###.## |
    苹果 | 20200306 | 20200405 | ###.## |
    ...
    ──────────────────────────────────────────

  2. 结果(名为dfSumS的数据框)
    ────────────────────────────────────────
    代码 | 日期组 | 平均 价格 | 坡度 | R-Square
    ────────────────────────────────────────
    AAPL | 20200205 | ###.## | #.## | #.##
    亚马逊 | 20200205 | ###.## | #.## | #.##
    ...
    苹果 | 20200305 | ###.## | #.## | #.##
    亚马逊 | 20200305 | ###.## | #.## | #.##
    ...
    ──────────────────────────────────────────


截至目前的代码

'prevdt' 对应上面的'Date Group','compcd' 表示公司代码

from sklearn.linear_model import LinearRegression

# Method Tried 1    
model = LinearRegression()   
def getRegrS(arg_cd, arg_prevdt):
    x = dfStock[(dfStock['compcd']==arg_cd) & (dfStock['prevdt']==arg_prevdt)]['rnk'].to_numpy().reshape((-1,1))
    y = dfStock[(dfStock['compcd']==arg_cd) & (dfStock['prevdt']==arg_prevdt)]['adjenp'].to_numpy()
    model.fit(x, y)
    return model.coef_[0], model.score(x,y)

# Method Tried 2
def getRegrS(arg_cd, arg_prevdt):
    x = dfStock[(dfStock['compcd']==arg_cd) & (dfStock['prevdt']==arg_prevdt)]['rnk'].to_numpy()
    y = dfStock[(dfStock['compcd']==arg_cd) & (dfStock['prevdt']==arg_prevdt)]['adjenp'].to_numpy()
    rv = stats.linregress(x,y)
    return rv[0], rv[2]
    
dfSumS['rnk'] = dfStock.groupby(['compcd','prevdt']).cumcount()+1
dfSumS[['slope','rsq']]= [getRegrS(cd, prevdt) for cd, prevdt in zip(dfSumS['compcd'], dfSumS['prevdt'])]

我以前尝试过的

根据此链接中的建议,我尝试了矢量化,但收到消息“只能比较标记相同的系列对象”。无法解决这个问题,我来了上面的两个函数,都不够快。两者都使用较小的代码集,例如 2020 年,但是一旦数据周期长到 2~3 个十年,就需要几个小时。

我想到了 apply、iterrows 等,但没有,因为首先链接说它比我做的慢,其次这些似乎只适用于一列,而我必须有两个结果 - 系数和 R 方在同一时期,因此两次调用它们肯定会更慢。

现在我正在尝试一些帖子中提到的游泳池

标签: pythonpandasoptimizationregression

解决方案


恐怕如果您尝试运行数千个大型线性回归,那么您将不得不为运行所花费的时间付出代价。numpy如果您只对 beta 系数或 r2 值感兴趣,则分别使用as(XtX)^(-1)Xty和分别计算它们可能更有效cov(X,y)/sqrt(var(X)var(y))


推荐阅读