Pandas实现同形状DataFrame按行n最大值取次日下一行对应值
Pandas实现TopN指标股次日收益提取方案
你之前提取每日TopN股票列名的思路完全可行,不需要绕弯做复杂的表关联,用shift提前对齐下一日数据,一步就能出结果。
核心逻辑
- 先对存储股票表现的DataFrame做向上移位,让每个日期索引对应的行,直接存储该日期下一个交易日的所有股票表现,避免逐行匹配索引的冗余操作
- 逐行遍历指标DataFrame,提取每行指标值最高的n只股票列名
- 直接从移位后的表现DataFrame中,取当前日期对应股票的下一日表现,和股票名拼接成最终结果
实现代码
import pandas as pd import numpy as np # 配置参数:取排名前3的股票 n = 3 # 步骤1:对齐下一日表现数据:shift(-1)表示把数据整体上移1行,当前日期行存储的就是次日数据 # 最后一行没有后续日期数据,会自动填充为NaN,属于正常情况 df_next_ret = df1.shift(-1) # 步骤2:逐行计算TopN股票及对应次日收益 def calc_topn(row): # 提取当前行指标值TopN的股票列名,若需要按绝对值排名加.abs()即可 top_stocks = row.nlargest(n).index.to_list() # 取对应股票的次日收益 top_rets = df_next_ret.loc[row.name, top_stocks].to_list() # 按字段格式返回 return pd.Series( top_stocks + top_rets, index = [f"Top{i+1}股票" for i in range(n)] + [f"Top{i+1}次日收益" for i in range(n)] ) # 生成最终结果 result = df.apply(calc_topn, axis=1)
结果说明
用你提供的测试数据运行后,输出结果结构如下:
| 日期 | Top1股票 | Top2股票 | Top3股票 | Top1次日收益 | Top2次日收益 | Top3次日收益 |
|---|---|---|---|---|---|---|
| 2021-01-01 | a | e | d | 1.2 | 2 | 0.5 |
| 2021-01-02 | e | h | i | 4.5 | 9 | 0.4 |
| 2021-01-03 | j | e | c | 5.6 | 1 | 5 |
| 2021-01-04 | i | a | j | NaN | NaN | NaN |
补充注意事项
- 如果两个DataFrame的日期索引不完全一致,先执行
df, df1 = df.align(df1, join="inner", axis=0)对齐交易日,再运行上述代码,避免日期错配 - 最后一行的NaN是因为没有后续交易日数据,回测时直接用
result = result.dropna()剔除即可 - 如果需要计算TopN等权组合的平均收益,直接新增一列即可:
ret_cols = [f"Top{i+1}次日收益" for i in range(n)] result["组合平均次日收益"] = result[ret_cols].mean(axis=1)
内容的提问来源于stack exchange,提问作者Pythonnewbie
相关产品推荐
相关产品推荐

