我历史上收集了大约 50 万笔贷款,其中一些已经违约,另一些则没有。我的数据框是 lcd_temp。 lcd_temp
包含有关贷款规模 (loan_amnt
)、贷款是否违约 (总违约
)、年贷款利率 ( clean_rate
)、贷款期限(clean_term
)以及从发起到违约的月份(mos_to_default
)。如果没有默认值,mos_to_default
等于 clean_term
。
我想计算每笔贷款的累积现金流 [cum_cf
],即违约前支付的所有优惠券的总和加上(1-严重性)(如果贷款违约),以及简单的 loan_amnt
如果按时还款的话。
这是我的代码,运行时间非常长:
severity = 1
for i in range (0,len(lcd_temp['Total_Defaults'])-1):
if (lcd_temp.loc[i,'Total_Defaults'] ==1):
# Default, pay coupon only until time of default, plus (1-severity)
lcd_temp.loc[i,'cum_cf'] = ((lcd_temp.loc[i,'mos_to_default'] /12) * lcd_temp.loc[i,'clean_rate'])+(1 severity)*lcd_temp.loc[i,'loan_amnt']
else:
# Total cf is sum of coupons (non compounded) + principal
lcd_temp.loc[i,'cum_cf'] = (1+lcd_temp.loc[i,'clean_term']/12* lcd_temp.loc[i,'clean_rate'])*lcd_temp.loc[i,'loan_amnt']
欢迎任何关于提高速度的想法或建议(到目前为止需要一个多小时)!
最佳答案
假设您使用的是 Pandas/NumPy,替换 if-then
结构(例如您正在使用的结构)的标准方法是使用 np.where(mask, A, B)
。 mask
是一个 bool 值数组。当 True 时,返回 A
中的相应值。当为 False 时,返回 B
中的相应值。结果是一个与 mask
形状相同的数组,其值来自 A
和/或 B
。
severity = 1
mask = (lcd_temp['Total_Defaults'] == 1)
A = (((lcd_temp['mos_to_default'] /12) * lcd_temp['clean_rate'])
+ (1 severity)*lcd_temp['loan_amnt'])
B = (1+lcd_temp['clean_term']/12 * lcd_temp['clean_rate'])*lcd_temp['loan_amnt']
lcd_temp['cum_cf'] = np.where(mask, A, B)
请注意,这对整列而不是逐行执行计算。这极大地提高了性能,因为它使 Pandas/NumPy 有机会将更大的值数组传递给快速的底层 C/Fortran 函数(在本例中是执行算术)。当您逐行工作时,您是在 Python 循环内执行标量算术,这使得 NumPy 发挥作用的机会为零。 如果您必须逐行计算,那么使用纯 Python 也同样(也许更好)。
尽管 A
和 B
计算整个列的值 - 并且某些值并未在 np.where< 返回的最终结果中使用
——假设行数较多,这仍然比逐行计算要快。
关于python - 我怎样才能使这个循环更有效率?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31764183/