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

Pandas长表格式下将股票收益率归一化到基期100的实现方法

Pandas长表结构下分组实现股票收益率归一化方案

完全可以直接对Stock列的每个唯一值分组计算Price列,不需要转换为宽表,也不需要编写for循环实现。

前置操作

首先需要确保数据集按「股票代码+日期」升序排序,避免计算顺序错误:

import pandas as pd
# 构造初始数据集
data = [['2020-01-01', 'A', 0.05], ['2020-01-02', 'A', 0.06], ['2020-01-03', 'A', 0.12], ['2020-01-04', 'A', 0.09], ['2020-01-05', 'A', 0.07],   ['2020-01-01', 'B', 0.10], ['2020-01-02', 'B', 0.20], ['2020-01-03', 'B', 0.15], ['2020-01-04', 'B', 0.12], ['2020-01-05', 'B', 0.18],    ['2020-01-01', 'C', 0.05], ['2020-01-02', 'C', 0.11], ['2020-01-03', 'C', 0.18], ['2020-01-04', 'C', 0.09], ['2020-01-05', 'C', 0.22]]
df = pd.DataFrame(data, columns = ['DATE', 'Stock', 'Return'])

# 按股票+日期排序保证计算顺序正确
df = df.sort_values(by=['Stock', 'DATE']).reset_index(drop=True)

实现方案

方案1:匹配你给出的示例结果

你提供的示例中Price的计算逻辑为「当期Return / 对应股票首日Return * 100」,一行代码即可实现:

df['Price'] = df['Return'] / df.groupby('Stock')['Return'].transform('first') * 100

运行后得到的结果和你给出的df2完全一致。

方案2:常规累计净值归一化(对应你之前宽表方法的逻辑)

如果是要计算首日为100的累计净值(即每日净值=前一日净值*(1+当日收益率)),可以用如下写法:

df['Price'] = df.groupby('Stock')['Return'].apply(lambda x: (x + 1).cumprod() / (x.iloc[0] + 1) * 100).reset_index(drop=True)

两种方案都全程保留长表结构,不需要做表结构转换,性能远高于手动写for循环遍历股票的实现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 08:39:03