You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python实现按季度与公司ID的列子集线性回归

按季度和公司ID分组线性回归并合并结果到原数据集

问题描述

我有一份日度股票收益数据集,需要按季度(qtr)和公司ID(PERMNO)将个股收益(FIRMRF)对市场收益(MKTRF)做线性回归,把每家公司每季度回归得到的斜率(beta)和标准误差存入原DataFrame,同一季度的回归值要在该季度的每一行重复显示。

数据集结构示例:

date  PERMNO          MCAP    FIRMRF   MKTRF  qtr
0       2018-01-02   10026  2.784892e+06 -0.017514  0.0085    1
7339    2018-01-03   10026  2.757077e+06 -0.010048  0.0059    1
14671   2018-01-04   10026  2.795160e+06  0.013753  0.0042    1
22003   2018-01-05   10026  2.768464e+06 -0.009610  0.0066    1
29334   2018-01-08   10026  2.770518e+06  0.000682  0.0019    1
...            ...     ...           ...       ...     ...  ...
8455011 2022-03-25   93436  1.044531e+09 -0.003235  0.0027    1
8464495 2022-03-28   93436  1.128454e+09  0.080345  0.0073    1
8473980 2022-03-29   93436  1.136443e+09  0.007080  0.0145    1
8483469 2022-03-30   93436  1.130676e+09 -0.005075 -0.0083    1
8492959 2022-03-31   93436  1.113736e+09 -0.014982 -0.0155    1

我当前的代码框架:

for i in daily['qtr']:
    for x in daily['PERMNO']:
        reg = sm.OLS(daily['FIRMRF'], sm.add_constant(daily['MKTRF']))
        results = reg.fit()

但这段代码没有实现分组回归的效果,尝试修改多个方案均失败,需要帮助。

解决方案

问题分析

当前代码的核心问题是没有按PERMNO和qtr分组处理,每次循环都用整个数据集做回归,并且错误地遍历了单个qtr和PERMNO值,而非对分组后的子数据集执行回归。

正确实现步骤

  1. 用pandas的groupby按PERMNO和qtr分组,对每个子数据集执行回归。
  2. 为每个分组提取MKTRF对应的系数(beta)和标准误差,生成包含分组键、beta、beta标准误差的新DataFrame。
  3. 将新DataFrame与原数据集按PERMNO和qtr合并,实现同一分组的所有行填充对应回归结果。

代码实现

import pandas as pd
import statsmodels.api as sm

# 定义回归函数,输入分组子数据集,返回beta及标准误差
def run_regression(group):
    # 处理样本量不足的情况,避免报错
    if len(group) < 2:
        return pd.Series({'beta': None, 'beta_std_err': None})
    X = sm.add_constant(group['MKTRF'])  # 添加截距项
    y = group['FIRMRF']
    model = sm.OLS(y, X).fit()
    return pd.Series({
        'beta': model.params['MKTRF'],
        'beta_std_err': model.bse['MKTRF']
    })

# 按公司和季度分组执行回归
reg_results = daily.groupby(['PERMNO', 'qtr']).apply(run_regression).reset_index()

# 合并回归结果到原数据集
daily_with_results = pd.merge(daily, reg_results, on=['PERMNO', 'qtr'], how='left')

关键说明

  • groupby(['PERMNO', 'qtr']):确保每个分组是单家公司单个季度的所有日度数据,避免跨公司或跨季度的错误回归。
  • apply(run_regression):自动对每个分组执行回归,返回的Series会与分组键组合成结构化的结果DataFrame。
  • pd.merge:通过双主键合并,保证原数据集中同一公司同一季度的所有行都能匹配到对应的beta值和标准误差。

额外提示

如果当前qtr仅为1-4的数字,建议结合年份生成复合季度标识(比如daily['year_qtr'] = daily['date'].dt.year * 10 + daily['qtr']),避免不同年份的同季度被错误归为一组。

内容的提问来源于stack exchange,提问作者AustinSobotka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 07:51:11