如何在摊销表for循环中用变量最后有效值填充至30期?
如何在摊销表循环中向下填充变量的最后有效值
我正在创建一个包含30个期间(索引1-30)的摊销表。问题是有个每期可能变化的变量llr_rate,目前只有前17行有有效值,后续行无值。想在for循环里把它的第17个(最后一个)有效值向下填充到第30行。
原代码如下:
beginning_bal = loan_amt principal = round(nf.ppmt(pv=loan_amt, rate=adj_interest_rate, nper=num_periods, per=num_periods, fv=0), 2) interest = nf.ipmt(pv=loan_amt, rate=adj_interest_rate, nper=num_periods, per=num_periods, fv=0) ending_bal = nf.pv(fv=0, pmt=pmt, rate=adj_interest_rate, nper=0) records=[] end_bal = loan_amt cum_int = 0.0 cof = 0.0 rt_npv = 0 for i in range(1, len(rng)+1): bgn_bal = end_bal principal = nf.ppmt(pv=loan_amt, rate=adj_interest_rate, nper=num_periods, per=i, fv=0) interest = float(nf.ipmt(pv=loan_amt, rate=adj_interest_rate, nper=num_periods, per=i, fv=0)) end_bal = nf.pv(fv=0, pmt=pmt, rate=adj_interest_rate, nper=len(rng)-i) monthly_co = loan_amt*co_rate npv_rate = 1.2**(i / num_payments_per_yr) npvper = -pmt / (npv_rate + co_rate + (.014*(12/num_payments_per_yr))) #20% discount, charge off rate, early payoff rate rt_npv += npvper cof += bgn_bal * .0083 #COF basis llr_rate.replace({'llr_rate': {0: np.nan}}).ffill() prin_llr = bgn_bal * llr_rate int_llr = -interest * llr_rate cum_int += interest net_revenue = (-cum_int - cof - monthly_co - prin_llr - int_llr) records.append((bgn_bal, -pmt, -principal, -interest, -cum_int, end_bal, monthly_co, npvper, rt_npv, npv_rate, cof, prin_llr, int_llr, net_revenue))
问题分析
原代码里的llr_rate.replace({'llr_rate': {0: np.nan}}).ffill()不会生效——这个操作返回的是一个新对象,没有赋值给llr_rate本身,所以原变量完全没变化。
解决方法
方法1:循环外提前完成填充
如果llr_rate是Pandas Series或DataFrame列,直接在循环外做向前填充,之后循环里直接用填充后的值:
# 循环外先处理llr_rate:把0替换成NaN,再向前填充 filled_llr_rate = llr_rate.replace(0, np.nan).ffill().values # 循环内直接取对应索引的值 for i in range(1, len(rng)+1): # ... 其他代码保持不变 ... current_llr = filled_llr_rate[i-1] # 因为i从1开始,数组索引从0开始 prin_llr = bgn_bal * current_llr int_llr = -interest * current_llr # ... 其他代码保持不变 ...
方法2:循环内判断并复用最后有效值
如果不想提前处理,也可以在循环外先拿到最后一个有效值,循环里超过17期就用这个值:
# 循环外提取所有有效值,取最后一个 valid_rates = [rate for rate in llr_rate if not pd.isna(rate) and rate != 0] last_valid_rate = valid_rates[-1] if valid_rates else 0 # 无有效值时的兜底值可自行调整 for i in range(1, len(rng)+1): # ... 其他代码保持不变 ... # 判断当前期数或当前rate是否有效 if i <= 17 and not pd.isna(llr_rate[i-1]) and llr_rate[i-1] != 0: current_llr = llr_rate[i-1] else: current_llr = last_valid_rate prin_llr = bgn_bal * current_llr int_llr = -interest * current_llr # ... 其他代码保持不变 ...
内容的提问来源于stack exchange,提问作者MDYETI
相关产品推荐
相关产品推荐

