如何针对不同规模的股票分组执行线性回归——解决Table B分组与Table A回归时的维度不匹配问题
解决思路&代码实现
我明白你的问题了——核心就是没把两个表的日期对齐,导致每个B组的行比A多,X和y长度不匹配。其实只要先把B里每个股票组的周数据和CCPM组的周数据按日期精准匹配,只保留两者都有的日期记录,再做回归就没问题了。下面给你一套具体的解决步骤和代码示例,用Python的pandas和statsmodels来实现:
第一步:数据预处理与对齐
首先要确保两个表的dt列是统一的日期格式,然后把CCPM组的周涨跌幅数据单独提取出来,再和Table B做内连接——这样每个B的股票组只会保留和CCPM组有相同周日期的行,保证X(CCPM的涨跌幅)和y(B组的涨跌幅)的长度完全一致。
import pandas as pd import statsmodels.api as sm # 确保日期列是datetime类型(如果原始数据不是的话) table_a['dt'] = pd.to_datetime(table_a['dt']) table_b['dt'] = pd.to_datetime(table_b['dt']) # 提取CCPM组的X数据(假设Table A只有CCPM组,若不是则加过滤条件:table_a[table_a['bbgid'] == 'CCPM']) ccpm_x = table_a[['dt', 'weekly_pct_change']].rename(columns={'weekly_pct_change': 'ccpm_pct'}) # 内连接Table B和CCPM的日期数据,只保留双方都有的周数据 merged_data = pd.merge(table_b, ccpm_x, on='dt', how='inner')
第二步:分组回归提取斜率
接下来定义一个回归函数,对每个股票组(按bbgid分组)执行线性回归,提取斜率。同时加入样本量判断,避免因样本太少导致的回归错误。
def calculate_slope(group): # 准备X和y:X是CCPM的涨跌幅,y是当前股票组的涨跌幅 X = sm.add_constant(group['ccpm_pct']) # 添加截距项,若不需要可删除 y = group['weekly_pct_change'] # 至少需要2个样本才能做线性回归 if len(X) < 2: return pd.Series({'bbgid': group['bbgid'].iloc[0], 'slope': float('nan')}) # 拟合OLS回归模型 model = sm.OLS(y, X).fit() # 返回股票ID和对应的斜率(ccpm_pct的系数就是我们要的相对走势斜率) return pd.Series({ 'bbgid': group['bbgid'].iloc[0], 'slope': model.params['ccpm_pct'], 'r_squared': model.rsquared # 可选:加入R²值评估拟合效果 }) # 按bbgid分组执行回归,得到每个股票组的斜率结果 slope_results = merged_data.groupby('bbgid').apply(calculate_slope).reset_index(drop=True)
关键注意点
- 如果你的Table A已经只包含CCPM组,那可以跳过
table_a[table_a['bbgid'] == 'CCPM']的过滤步骤。 - 内连接会自动剔除B组中与CCPM组没有重叠日期的行,确保X和y长度一致,解决「X和y必须尺寸相同」的错误。
- 函数里的样本量判断是为了避免某些股票组重叠日期太少(比如只有1周)导致回归失败,这类组会返回
NaN,你可以后续用slope_results.dropna()过滤掉。 - 如果你不需要回归截距,直接把
sm.add_constant去掉,用X = group['ccpm_pct']即可,但通常建议保留截距项以保证回归的合理性。
内容的提问来源于stack exchange,提问作者Miguel 2488
相关产品推荐
相关产品推荐

