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

Pandas DataFrame单元格依赖场景下NaN值高效填充方案咨询

解决方案

问题原因

原有代码为整列向量化计算,计算时所有行的PresentValue只有第一行有初始值,后续行均为NaN,且计算过程中不会自动用上一行的FinalPresentValue更新下一行的PresentValue,因此后续列的计算结果全部为NaN。

实现方案

对于这种行级前向依赖的计算,最直观易维护的实现是先计算无依赖的固定列,再逐行迭代计算有依赖的列。你当前的场景只有6行数据,循环计算的性能完全够用。

完整代码

import pandas as pd
import numpy as np

Initial_Investment = 7.5 * 10**9 # 10^9 ~ 10亿
Initial_Loan = 12.5 * 10**9
Initial_Portfolio_Value = 20 * 10**9 
Portfolio_Duration = 10 # 麦考利久期
Initial_Short_Term_Rate = 0.06
Initial_Coupon_Rate = 0.085 
Initial_Loan_Rate = 0.07

years = np.arange(1991,1997,1) # 1991-1996
interest_rate_change = np.array([-0.005, -0.005, -0.005, -0.005, 0.02, 0.02]) 

df = pd.DataFrame({'Year':years, 'PresentValue':np.nan, 'InterestRateChange':interest_rate_change})

# 先计算无前置依赖的列,不需要参与循环
df['ShortTermRates'] = df['InterestRateChange'].shift(1,fill_value=Initial_Short_Term_Rate).cumsum()
df['CouponRates'] = df['InterestRateChange'].shift(1,fill_value=Initial_Coupon_Rate).cumsum()
df['LoanRates'] = df['InterestRateChange'].shift(1,fill_value=Initial_Loan_Rate).cumsum()
df['LoanPayment'] = df['LoanRates'] * -Initial_Loan

# 初始化第一行数据
df.loc[0, 'PresentValue'] = Initial_Portfolio_Value
df.loc[0, 'DeltaPrice'] = df.loc[0, 'InterestRateChange'] * df.loc[0, 'PresentValue'] * -Portfolio_Duration
df.loc[0, 'CouponEarning'] = df.loc[0, 'CouponRates'] * df.loc[0, 'PresentValue']
df.loc[0, 'Earnings/Loss'] = df.loc[0, 'DeltaPrice'] + df.loc[0, 'CouponEarning'] + df.loc[0, 'LoanPayment']
df.loc[0, 'FinalPresentValue'] = df.loc[0, 'PresentValue'] + df.loc[0, 'Earnings/Loss']

# 逐行计算后续行
for i in range(1, len(df)):
    # 当期现值等于上一期期末现值
    df.loc[i, 'PresentValue'] = df.loc[i-1, 'FinalPresentValue']
    # 计算当期其他依赖列
    df.loc[i, 'DeltaPrice'] = df.loc[i, 'InterestRateChange'] * df.loc[i, 'PresentValue'] * -Portfolio_Duration
    df.loc[i, 'CouponEarning'] = df.loc[i, 'CouponRates'] * df.loc[i, 'PresentValue']
    df.loc[i, 'Earnings/Loss'] = df.loc[i, 'DeltaPrice'] + df.loc[i, 'CouponEarning'] + df.loc[i, 'LoanPayment']
    df.loc[i, 'FinalPresentValue'] = df.loc[i, 'PresentValue'] + df.loc[i, 'Earnings/Loss']

print(df.round(2))

扩展说明

如果后续数据量上升到万行以上,可以用numba装饰器加速循环,或者将计算逻辑抽象为累积函数用numpy.frompyfunc实现向量化累积计算,对于小数据量上述循环方案足够简洁易维护。

内容的提问来源于stack exchange,提问作者sir.isaac.newton

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 02:06:04