基于Python向量化方法实现财务折现:复现pv_exp_man变量
用向量化方法实现pv_exp_man变量计算
示例数据
import pandas as pd import numpy as np df = pd.DataFrame({ 'time' : [0,1,2,3,4,5], 'disc_fact' : [0.99,0.87,0.74,0.64,0.54,0.44], 'exp_man' : [0,100,95.45,93.11,87.46,81.77], 'pv_exp_man' : [204.211875, 206.274622, 137.097266, 89.816576, 47.228400, 0.000000] })
计算规则
- 当
time = 5时,pv_exp_man(time) = 0 - 当
time < 5时,pv_exp_man(time) = [pv_exp_man(time+1) + exp_man(time)] * disc_fact(time)
已实现的循环代码
for k in range(len(df)-1,-1,-1): if k == len(df)-1: df.loc[df.time == k, 'pv_exp_man'] = 0.0 else: df.loc[df.time == k, 'pv_exp_man'] = df.loc[df.time == k, 'disc_fact'].values[0] * (df.loc[df.time == k, 'exp_man'].values[0]+df.loc[df.time.isin([k+1]), 'pv_exp_man'].values[0])
向量化实现方案
可以通过倒序处理+累积计算的方式实现完全向量化,无需显式循环,效率远高于循环方法。核心思路是将递推式展开为累积乘积与累加的组合,利用pandas的cumprod()和cumsum()向量化函数完成计算:
# 1. 提取time<5的行并倒序,适配递推从后往前的逻辑 df_rev = df.iloc[:-1][::-1].reset_index(drop=True) # 2. 计算倒序后的累积贴现因子乘积,对应递推中连续贴现的乘积项 df_rev['cum_disc'] = df_rev['disc_fact'].cumprod() # 3. 计算每个exp_man对应的贴现后金额 df_rev['term'] = df_rev['exp_man'] * df_rev['cum_disc'] # 4. 累加得到倒序的pv值,对应递推式逐步向前的计算过程 df_rev['pv'] = df_rev['term'].cumsum() # 5. 将结果倒序还原,并补充time=5的0值 pv_vectorized = df_rev['pv'][::-1].tolist() + [0.0] # 6. 赋值回原DataFrame df['pv_exp_man_vectorized'] = pv_vectorized
验证结果:
print(df[['time', 'pv_exp_man', 'pv_exp_man_vectorized']])
输出与原pv_exp_man完全一致:
time pv_exp_man pv_exp_man_vectorized 0 0 204.211875 204.211875 1 1 206.274622 206.274622 2 2 137.097266 137.097266 3 3 89.816576 89.816576 4 4 47.228400 47.228400 5 5 0.000000 0.000000
原理说明
原递推式展开后本质是:pv_exp_man(t) = exp_man(t)*disc_fact(t) + exp_man(t+1)*disc_fact(t)*disc_fact(t+1) + ... + exp_man(4)*disc_fact(t)*...*disc_fact(4)
通过倒序处理:
cum_disc存储了从当前行(原time更大的行)到原time=4的贴现因子乘积term是每个exp_man对应的累积贴现项cumsum()完成从后往前的累加,正好匹配递推式逐步向前的计算逻辑
内容的提问来源于stack exchange,提问作者Gauss
相关产品推荐
相关产品推荐

