首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >因子分十组不一定真有十组:qcut 遇到重复值怎么处理

因子分十组不一定真有十组:qcut 遇到重复值怎么处理

原创
作者头像
量化行业新引擎
发布于 2026-10-10 14:16:00
发布于 2026-10-10 14:16:00
430
举报
文章被收录于专栏:AI量化视界AI量化视界

做因子分层回测时,常见写法是按交易日把股票等分成十组,再观察各组收益是否单调。代码看起来很简单:`pd.qcut(factor, 10)`。但如果因子里有大量重复值,十组未必能顺利生成,最典型的场景是停牌标记、离散评分,或者经过截断后大量样本都落在同一个边界上。

pandas 官方文档说明,`qcut` 是按样本排名或样本分位点切箱;当分箱边界不唯一时,默认会抛出异常。把 `duplicates="drop"` 加上去虽然能继续运行,但它会直接减少箱数。原本设计的十组可能只剩七组,如果后面的代码仍把标签 0 到 9 当成固定组合,收益统计就会出现空组,跨日期比较也会失去统一含义。

我更倾向于先检查当日有效样本数和不同取值数量,再决定分组方式:

def make_group(s, n=10):

valid = s.dropna()

if len(valid) < n or valid.nunique() < n:

return pd.Series(pd.NA, index=s.index, dtype="Int64")

rank = valid.rank(method="average", pct=True)

group = ((rank * n).clip(upper=n) - 1).astype("Int64")

return group.reindex(s.index)

df["group"] = df.groupby("trade_date")["factor"].transform(make_group)

这里使用平均排名,是为了让相同因子值留在同一组,不靠原始行顺序强行拆开并列样本。代价是每组股票数不一定完全相等,但这通常比“同一个因子值随机分到不同组合”更容易解释。若业务确实要求每组数量接近,可以使用 `rank(method="first")` 后再切分,不过必须先按稳定字段排序,否则数据读取顺序变化就可能改变分组结果。

回测输出里最好同时记录计划组数、实际组数、每组样本量和分箱边界。遇到有效股票过少、唯一值不足或某组占比异常时,直接跳过该日或标记质量问题,而不是悄悄补齐标签。分层回测关注的不只是能否算出收益,更重要的是每天的组合定义是否一致、可解释、可复现。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档