如何基于Numpy的pct_change(600)反向还原累计变化?
还原600周期涨跌幅的累计变化序列
核心逻辑理解
df["mid_price"].pct_change(600) 计算的是当前值与600期前值的涨跌幅,即:
ema_10_diff[i] = (mid_price[i] / mid_price[i-600]) - 1
反向推导可得:
mid_price[i] = mid_price[i-600] * (1 + ema_10_diff[i])
我们需要构建的累计序列(起始值为1),本质是基于这个关系,逐步递推或插值得到连续的累计变化。
方案1:仅计算600周期节点的累计值(向量化实现)
如果只需要在每600期的位置得到累计值,中间位置保留NaN,可以用向量化操作避免循环,效率更高:
import pandas as pd # 初始化累计序列,起始值为1 df["cumulative"] = 1.0 # 筛选出索引≥600的行(即有600期前数据的行) valid_idx = df.index >= 600 # 递推计算累计值:当前累计值 = 600期前累计值 * (1 + 当期涨跌幅) df.loc[valid_idx, "cumulative"] = df["cumulative"].shift(600)[valid_idx] * (1 + df["ema_10_diff"][valid_idx])
方案2:生成连续的累计序列(几何插值填充)
如果需要连续的累计变化序列(中间无NaN),可以先计算600周期节点的累计值,再通过几何插值填充中间值(符合金融数据的复利增长逻辑):
import pandas as pd import numpy as np # 步骤1:计算600周期节点的累计值 df["cumulative_600"] = 1.0 for i in range(600, len(df), 600): if pd.notna(df["ema_10_diff"].iloc[i]): df["cumulative_600"].iloc[i] = df["cumulative_600"].iloc[i-600] * (1 + df["ema_10_diff"].iloc[i]) # 步骤2:对数转换后线性插值,再指数还原实现几何插值 df["log_cumul"] = np.log(df["cumulative_600"]) df["log_cumul"] = df["log_cumul"].interpolate(method="linear") df["cumulative"] = np.exp(df["log_cumul"]) # 清理临时列 df.drop(["cumulative_600", "log_cumul"], axis=1, inplace=True)
说明
- 若你的DataFrame是时间索引(而非整数索引),只需将
range(600, len(df), 600)替换为按时间步长筛选的逻辑(比如df.resample("600T").last().index)即可适配。 - 前600期没有600期前的参考数据,若需要这部分的累计值,必须依赖原始的
mid_price(计算mid_price/mid_price.iloc[0]),仅靠ema_10_diff无法推导。
内容的提问来源于stack exchange,提问作者Erik Storm
相关产品推荐
相关产品推荐

