对几种常见贷款进行数据分析
最近在看《Python编程导论》(第二版), 看到类那一章时,后面有个对比几种不同类型贷款的例子,有一天在回看时,突然发现,这不就是一种量化的方式么?之前本来是草草地一带而过,现在又来了兴趣,打算仔细研究研究。
注:本文对书中原有的代码基本不做改动,主要通过注释的方式进行说明,并增加了另一种贷款方式进行比较,旨在帮助大家对代码做进一步分析。
def findPayment(loan, r, m):# 计算在贷款额loan 月利率r和期限m个月下,每月需返还的固定金额return loan * ((r * (1 + r) ** m) / ((1 + r) ** m - 1))
class Mortgage(object):# 构建贷款类, 定义四种贷款都有的属性def __init__(self, loan, annRate, months):self.loan = loan # 贷款总额self.rate = annRate / 12 # 将年利率转化为月利率self.months = months # 还款月数self.paid = [0.0] # 已支付金额self.outstanding = [loan] # 剩余本金self.payment = findPayment(loan, self.rate, months) # 每月还款金额, 默认按照等额本息的方式self.legend = None # 贷款描述def makePayment(self):# 还款函数,调用此函数进行还款self.paid.append(self.payment)reduction = self.payment - self.outstanding[-1] * self.rate # 还款金额中的本金self.outstanding.append(self.outstanding[-1] - reduction) # 记录剩余本金def getTotalPaid(self):# 返回已支付贷款总额return sum(self.paid)def __str__(self):# 返回贷款描述return self.legend
class Fixed(Mortgage):
# 等额本息子类
# 只需继承Mortgage(),重写描述属性self.legend即可def __init__(self, loan, r, months):Mortgage.__init__(self, loan, r, months)self.legend = "等额本息, " + str(round(r * 100, 2)) + '%'
def totalCapitalPayment(loan, months, r):
# 等额本金类贷款每个月要还的本金不变,而利息是随着还款月数的增加而减少的,所以定义一个函数,直接返回一个包含每月还款金额的列表即可total = []for m in range(months):total.append(loan / months + (loan - m * (loan / months)) * r)return totalclass FixedCapital(Mortgage):# 等额本金子类def __init__(self, loan, r, months):Mortgage.__init__(self, loan, r, months)# self.payment =capitalPayment(loan, r, months)self.capital = loan / monthsself.total = totalCapitalPayment(loan, months, self.rate)self.legend = "等额本金, " + str(round(r * 100, 2)) + '%'def makePayment(self, m):# 由于等额本金的每月还款额与当前还款月数相关,所以引入还款月数mself.paid.append(self.total[m])# 本期剩余本金 = 上期剩余本金 - 每月固定本金self.outstanding.append(self.outstanding[-1] - self.capital)
class FixedWithPts(Mortgage):# 固定点数子类def __init__(self, loan, r, months, pts):Mortgage.__init__(self, loan, r, months)self.pts = pts # 固定点数# 计算第一次按照固定点数还款的金额self.paid = [self.loan * (self.pts / 100)]self.legend = "固定点数, " + str(round(r * 100, 2)) + '%, ' + str(pts) + ' points'
class TwoRate(Mortgage):# 双利率子类def __init__(self, loan, r, months, teaserRate, teaserMonths):Mortgage.__init__(self, loan, teaserRate, months)self.teaserMonths = teaserMonths # 前期低利率月数self.teaserRate = teaserRate # 前期低利率self.nextRate = r / 12 # 后期高利率self.legend = '双利率, ' + str(teaserRate * 100) + '% for ' + str(self.teaserMonths) + ' months, then ' + \str(round(r * 100, 2)) + '%'def makePayment(self):# 如果到达teaserMonths,则使用self.nextRate高利率,后面每月的付款金额按照剩余本金、利率和月数重新计算if len(self.paid) - 1 == self.teaserMonths:self.rate = self.nextRateself.payment = findPayment(self.outstanding[-1], self.rate, self.months - self.teaserMonths)Mortgage.makePayment(self) # 未到达teaserMonths时,每月的还款金额
def compareMortgages(amt, years, fixedRate, pts, ptsRate, lowRate, highRate, lowMonths):# 比较各类贷款的总还款额totMonths = years * 12fixed1 = Fixed(amt, fixedRate, totMonths)fixed2 = FixedCapital(amt, fixedRate, totMonths)fixed3 = FixedWithPts(amt, ptsRate, totMonths, pts)twoRate = TwoRate(amt, highRate, totMonths, lowRate, lowMonths)morts = [fixed1, fixed3, twoRate] # 先对除等额本金外的其他三类贷款进行还款for m in range(totMonths):for mort in morts:mort.makePayment()fixed2.makePayment(m) # 单独调用包含参数m的等额本金还款参数morts.insert(1, fixed2) # 还款完毕后再加入贷款列表# 展示四种贷款方式各自的还款总额for m in morts:print(m)print(" Total payments = $" + str(int(m.getTotalPaid())))# 带入实际的值进行比较:
compareMortgages(200000, 30, 0.07, 3.25, 0.05, 0.045, 0.095, 48)
# 比较结果
Fixed, 7.0%
Total payments = $479017
Fixed Capital, 7.0%
Total payments = $410583
Fixed, 5.0%, 3.25 points
Total payments = $393011
4.5% for 48 months, then 9.5%
Total payments = $551444
从比较结果可以看出,还款总额从高到低依次为:
双利率 > 等额本息 > 等额本金 > 固定点数
def plotPayments(self, style):
# 统计每月还款额pylab.plot(self.paid[1:], style, label=self.legend)def plotTotPd(self, style):
# 统计每月还款总额totPd = [self.paid[0]]for i in range(len(self.paid)):totPd.append(totPd[-1] + self.paid[i])pylab.plot(totPd, style, label=self.legend)def plotBalance(self, style):
# 统计每月剩余本金pylab.plot(self.outstanding, style, label=self.legend)def plotNet(self, style):# 统计每月支付总利息totPd = [self.paid[0]]for i in range(1, len(self.paid)):totPd.append(totPd[-1] + self.paid[i])# 先通过数组计算出每月偿还的本金(贷款总额 - 每月剩余本金)equityAcquired = pylab.array([self.loan] * len(self.outstanding)) - pylab.array(self.outstanding)# 再用每月的总还款额 - 每月偿还本金 = 每月偿还利息net = pylab.array(totPd) - equityAcquiredpylab.plot(net, style, label=self.legend)
def plotMortgages(morts, amt):def labelPlot(figure, title, xLabel, yLabel):pylab.figure(figure) # 指定当前图,即绘制前要先指定图的figure值pylab.title(title) # 设置标题pylab.xlabel(xLabel) # 设置x轴标签pylab.ylabel(yLabel) # 设置y轴标签pylab.legend(loc='best') # 将描述信息放在不与曲线冲突的最合适区域styles = ['k-', 'k-.', 'k:', 'b-'] # 设置各类贷款对应的曲线样式payments, cost, balance, netCost = 0, 1, 2, 3 # 设置图的figure,对各类曲线按照指标分类for i in range(len(morts)):pylab.figure(payments) # 根据figure值,将各类曲线绘制到对应的图中morts[i].plotPayments(styles[i]) # 月还款额pylab.figure(cost)morts[i].plotTotPd(styles[i]) # 总还款额pylab.figure(balance)morts[i].plotBalance(styles[i]) # 剩余本金pylab.figure(netCost)morts[i].plotNet(styles[i]) # 月支付利息labelPlot(payments, '贷款' + str(amt) + '元的每月还款情况', '月数', '月还款金额')labelPlot(cost, '贷款' + str(amt) + '元的还款总额', '月数', '已支付金额')labelPlot(balance, '贷款' + str(amt) + '元的每月本金剩余情况', '月数', '剩余未还本金')labelPlot(netCost, '贷款' + str(amt) + '元的累计利息支付情况', '月数', '支付的累计利息')
def compareMortgages(amt, years, fixedRate, pts, ptsRate, lowRate, highRate, lowMonths):# 比较各类贷款的总还款额totMonths = years * 12""" ... 此处省略前面的部分代码 ... """# for m in morts:# print(m)
# print(" Total payments = $" + str(int(m.getTotalPaid())))
# 展示四种贷款方式的对比曲线plotMortgages(morts, amt)pylab.show()
import matplotlib
# 修改默认字体
matplotlib.rcParams['font.sans-serif'] = ['SimHei']
matplotlib.rcParams['font.family'] = 'sans-serif'
![](/assets/blank.gif)
可以看出,等额本息和固定点数从始至终都维持着恒定的还款金额,但是由于固定点数提前还了一部分的贷款,所以后期支付的金额就会少一些;
![](/assets/blank.gif)
该图反映了总还款额随时间变化的情况。如果对比最后贷款结束时的还款金额,很明显,固定点数 < 等额本金 < 等额本息 < 双利率。
![](/assets/blank.gif)
![](/assets/blank.gif)
转载于:https://www.cnblogs.com/dev-liu/p/python_analysis_loan.html
对几种常见贷款进行数据分析相关推荐
- 七种常见的数据分析法之:可行域分析
导读 福格模型的触发有效区,我们就将其称之为可行域.那么,可行域分析该怎么用呢? 大数据产业创新服务媒体 官网 | www.datayuan.cn 今日头条丨一点资讯丨腾讯丨搜狐丨网易丨凤凰丨阿里UC ...
- 七种常见的数据分析方法拆解
数据分析一直是互联网人辨别方向的不二法门,我们通过对数据的观测来判断事物的发展趋势,也常常利用数据的思维来辩证的为决策做参考. 下面就给大家详细拆解七种常见的数据分析法,让我们的数据分析少走弯路. 0 ...
- 几种常见的数据分析方法拆解
数据分析一直是我们互联网人辨别方向的不二法门,我们通过对数据的观测来判断事物的发展趋势,也常常利用数据的思维来辩证的为决策做参考. 掌握技能和工具只是第一步,做好数据分析还必须要有数据分析思维.数据思 ...
- 机器学习中用到的概率知识_山顶洞人学机器学习之——几种常见的概率分布
机器学习是实现人工智能的重要技术之一.在学习机器学习的过程中,必须要掌握一些基础的数学与统计知识.之前的两篇文章我们分别讲述了中心极限定理与大数定律,它们是数据分析的理论基础.今天我们来介绍几种常见的 ...
- python sns绘制回归线_【干货!】用Python演绎5种常见可视化视图
- 点击上方"中国统计网"订阅我吧!- 通过本篇文章,你将学到: 视图的分类,从哪些维度进行分类 5种常见视图的概念,以及如何在Python中进行使用,都需要用到哪些函数. 注意: ...
- 为何大量网站不能抓取?爬虫突破封禁的6种常见方法
为何大量网站不能抓取?爬虫突破封禁的6种常见方法 在互联网上进行自动数据采集(抓取)这件事和互联网存在的时间差不多一样长.今天大众好像更倾向于用"网络数据采集",有时会把网络数据采 ...
- 10种常见的回归算法总结和介绍
线性回归是机器学习中最简单的算法,它可以通过不同的方式进行训练. 在本文中,我们将介绍以下回归算法:线性回归.Robust 回归.Ridge 回归.LASSO 回归.Elastic Net.多项式回归 ...
- [数据分析干货]四种简单常用的数据分析方法,学完立马升职加薪!
你是否做了N个渠道推广,却不知道钱花的效果怎么样? 你是否用数据做了很多图表,但是只知道表象却不会深入分析现象背后发生了什么,得不出什么有效的结论? 今天就来给大家分享4种最常用的数据分析方法,让你在 ...
- 电池管理系统(BMS)功能与作用/BMS 故障分析方法/15种常见故障案例分析
提示:本篇文章仅供学习参考 文章目录 一.电池管理系统(BMS)功能与作用 二.BMS 故障分析方法 三.15种常见故障案例分析 一.电池管理系统(BMS)功能与作用 从整车角度,电池管理系统(BMS ...
最新文章
- 用GPIO口模拟串口通信,它真的来了
- NG Updata(升级)
- CSS3实现圆角效果
- AcWing 841. 字符串哈希(字符串Hash)
- 关于net2.0里面新出现的类backgroundworker的应用
- mysql-备份和还原(普通还原和binlog还原)
- 按照某列属性拆分Excel文件
- 拓端tecdat|互联网热门职位薪资对比报告
- 监听下拉框,当前选中值
- 【语音识别】基于matlab功率谱和倍频法男女生识别【含Matlab源码 705期】
- postSQL安装和GIS数据导入
- SpringSecurity视频教程
- DBF文件初步了解(二)——DBF数据导出代码实现
- 微搭低代码Tab栏组件使用指南
- 加载大图片,内存溢出问题
- 搭建商城系统怎么选择合适的运营模式?
- (亲测很实用)地理位置批量转经纬度,基于百度地图api
- 正确使用数字化仪前端信号调理功能
- 向企业微信发送文字、图片的接口【亲测有效】
- 涉密信息系统集成资质申请单位提交材料清单
热门文章
- java 图像识别 头部,翻拍识别示例_图像识别 Image_SDK参考_使用SDK(Java)_华为云...
- CAD机械设计数字化管理,项目决策快人一步
- 博物馆RFID出入库管理系统解决方案--RFID出入库-文物仓库管理-新导智能
- Windows 7 64位 HookApi例子
- C语言编程对一个逆波兰式进行求值,算式与逆波兰式
- clickhouse集群表删除_Clickhouse 分布式表本地表
- [ACTF2020 新生赛]Upload 1
- 海南电信公网固定IP申请及ICP备案过程
- 微型计算机的由来思维导图,央视专访:思维导图的由来!看发明人博赞先生怎么说~...
- VueJS 的VNode