关于如何使用python进行数据分析的文章很多,相关的书籍也有很多。本文是基于Excel思维使用python进行数据分析,换句话说就是本文不是传统意义上的专业python文章。文章的内容共分为8个部分,从最基础的数据导入和读取到分析结果的图表化输出。这其中包含了很多与Excel非常相似的函数和分析功能,如SUM ,COUNTIF,TRANSPOSE函数,以及数据筛选,分类汇总和数据透视表等功能等等,这些在python中都能找到对应的代码。因此,只要你会使用基本的Excel函数就能看懂文中的python代码,并可以使用Python进行简单的数据分析。文章中的数据源来自Lending Club 2017-2011年的公开数据。
使用Python进行数据分析之前,需要预先导入相对应的功能库。数据分析最常用的库包括用于数值计算的numpy,基于numpy构建的用于科学计算的Pandas库,用于数据可视化的matplotlib和提供各种操作系统功能接口的OS库。我们将这几个库导入到python中, import后是导入库的名称 as后是库的简称。例如pandas库
的简称是pd,在后面的代码中看到pd就表示这个操作使用了pandas库。具体代码如下:
import os as os import pandas as pd import numpy as np import matplotlib.pyplot as plt
导入功能库后,就可以开始读取数据了。这里需要注意的是如果数据文件没有保存在Jupyter Notebook的工作目录中,在导入的过程中需要说明数据所在的路径。如果你觉得输入路径太麻烦的话,可以使用OS库查看或更高操作系统中的工作目录。将数据文件直接拷到Jupyter Notebook的工作目录中,通过下面的代码可
以查看Jupyter Notebook的工作目录位置。
os.getcwd()
或者将数据所在位置的路径设置为工作目录。具体方法如下:
os.chdir('C:\\Users\\cliffwang\\Desktop\\python')
我们将Lending Club的数据保存在Jupyter Notebook工作目录开始读取数据。Python可以读取多种数据格式,如csv,xls和txt等等。Lending Club的数据源是csv格式的。我们通过下面的代码完成读取数据和创建数据表的工作。
lc=pd.DataFrame(pd.read_csv('LoanStats3a.csv',header=1))
在上面读取数据的代码中,使用了pandas库(pd)中的功能,首先读取LoanStats3a.csv文件,并设置标题行header=1。然后将读取的csv文件转成DataFrame并将这个数据表取名lc。
数据读取工作完成后,可以开始对数据进行简单的预览。预览内容主要包括了解数据表的大小,字段的名称,数据格式等等。为接下来的数据分析工作做准备。
首先查看我们刚刚读取数据表的大小。通过下面的的结果可以看到Lending Club的数据表有4万多行,111个字段。想要进一步查看数据表中更具体的内容可以通过后面的代码来实现。
lc.shape
Columns是查看表中各个字段名称的代码,以方便后续的分析工作。这里由于字段数量较多,python只列出了一部分字段的名称。
lc.columns
我们继续查看数据表中具体的数据内容,由于这个数据表行数较多我们不查看所有数据,只查看开始和结束的几行。下面的的结果中显示了数据表前5行的数据内容。head后面的()括号中可以输入要查看的具体行数,为空时默认只显示前5行的数据。在前5行的数据表中可以发现,很多字段中都是NaN值,这可能导致后面
的字段不可用。不过到底包含多少NaN值,我们在后面的数据清洗部门会进行详细的统计。
lc.head()
tail显示数据表尾部的数据,和head一样tail后面的()中可以输入要查看的具体行数,这里我们输入3表示查看数据表后3行的数据。为空时默认显示最后5行的数据。下面的结果中可以看出id字段最后两行包含了一些其他的信息,而其他字段中并不包含这些信息是NaN值。
lc.tail(3)
最后查看数据表中各个字段的类型,确定数据表中包含哪些类型的数据,是否需要进行格式转换等等。这里发现日期字段的格式为object,需要转换为日期格式。
lc.dtypes
在数据内容概览部分我们大致了解了数据表中的信息,同时也发现表中包含很多NaN值,以及日期格式转换的问题。这些问题将在后面的数据清洗部分进行解决。
在数据概览部分中发现的问题需要通过数据清洗进行解决。这部分主要解决前面发现的NaN值和日期格式转换问题。通过查看数据表中的空值情况可以发现,前面的字段中NaN值较少,NaN值主要集中在后面的一些字段中。
lc.isnull()
对前面查看的NaN值情况使用SUM进行汇总,可以获得每个字段中具体的NaN值数量。在下面的结果中,除了id字段以外,几乎每个字段都有NaN值。在数据预览的部分,我们发现id值后面有两行汇总数据,因此判断Member,loan_amnt等前面的大部分字段的NaN值是由于这最后这两行信息造成的。而后面字段NaN值达到了4
万多条,几乎与数据表总行数一致,因此我们舍弃这些字段,只对前面的字段进行统计。
lc.isnull().sum()
在python中解决NaN值有两个方法,可以统一填充为0,也可以将包含NaN值的行删除。我们先保留这些字段,在后面的使用过程中再进行填充。
对于日期字段我们使用to_datetime来进行日期格式的转换。下面的命令中将数据表中的issue_d字段更改为日期格式并重新赋给issue_d字段。从查看的结果中可以看出通过格式转换issue_d字段的格式已经从object变成了datetime64。
lc['issue_d']=pd.to_datetime(lc['issue_d'])
清洗后的数据表可以开始进行分析工作,首先是对一些关键汇总指标的统计,对于Lending Club这些关键指标包括总贷款次数,总贷款金额,总利息收入等等。
对数据表中member_id字段进行计数,获得总的贷款次数。这与Excel中的count函数基本一致。
lc['member_id'].count()
对数据表中member_id字段进行唯一值计数,获得总贷款人数。这里贷款次数与人数基本一致。猜测这个值应为贷款次数。
len(lc['member_id'].unique())
对数据表中loan_amnt字段进行求和,获得总贷款金额。这与Excel中的sum函数基本一致。
lc['loan_amnt'].sum()
将贷款金额分布绘制成箱线图可以看出,贷款均值为10000元。大部分贷款的金额都集中在5000到15000之间。
plt.boxplot(lc[‘loan_amnt’])
plt.show()
[/code]
换成直方图再看下,5000美金一个区间,与之前的结果类似,15000以下的贷款居多,其中最多的是5000到10000的区间。大额的贷款也有但笔数较少,最高的一笔35000美金。这些绘图功能我们使用了matplotlib库(plt)。
bins = [0, 5000, 10000, 15000, 20000, 25000, 30000, 35000, 40000] plt.hist(lc['loan_amnt'],bins,normed=1, histtype='bar', rwidth=1) plt.show()
从2017到2011年贷款笔数增长趋势看,虽然中间贷款笔数整体呈快速增长趋势,并且增长速度非常快,从开始每月几十笔到近2500笔。这应该与美国人的理财观念有关系。在后面的贷款用途分析中也可以发现,他们的贷款目的和用途非常广泛,有些甚至有点奇怪。贷款目的可能是为了一次旅行,结婚,甚至还有一个贷
款目的写的是为了自由。
lc.sort(columns='issue_d',ascending=False) issue_date=lc.groupby('issue_d').count() plt.plot(issue_date['member_id'],linewidth=3) plt.show()
继续对数据表中total_rec_in字段进行求和,获得总利息收入金额。除了利息收入以外,Lending Club还有一部分收入是罚息和类似手续费的收入。这里我们并没有包括这些收入,只是简单sum了贷款利息收入。
lc['total_rec_int'].sum()
最后再对表中各个字段做个描述统计,看下数据的集中度与离散情况,这里主要关注最大值,最小值和标准差等。由于字段较多,我们在描述统计的命令后面加了一个.T,对数据进行转置,这相当于Excel中的TRANSPOSE函数。
lc.describe().T
从描述统计的结果可以发现,贷款的最小金额为500美金,最大金额为35000美金。用户收入最少为1896美金,最多为6000000美金。
Lending Club的数据表中包含很多与用户相关的字段,例如用户收入,贷款用途,用户等级,职位,所在地区等等。我们可以通过这些字段从多个维度做个贷款用户画像。
首先是收入情况,Lending Club的贷款用户收入差距还是挺高的,从1-2万美金/年到30-40万美金/年的都有。我们以5万美金/年对贷款用户的收入分布进行了统计。从下面的直方图中可以看出,大部分贷款用户收入在10万美金/年以下。高收入的贷款用户数量很少。
bins = [0, 50000, 100000, 150000, 200000, 250000, 300000, 350000, 400000, 450000] plt.hist(lc['annual_inc'],bins, histtype='bar', rwidth=1) plt.show()
前面的贷款金额分布与用户收入非常相似,小额贷款高于大额贷款。那么贷款金额的大小与贷款用户的收入之间是否有联系呢?我们对用户收入和贷款金额进行相关分析。从下面的结果中可以看出两者的相关系数仅为0.27,推翻了我们之前的假设,也就是说并不是收入越高的人贷款金额也越高。
c=lc[['annual_inc','loan_amnt']] c.corr()
了解了用户的收入分布情况后,我们再来逐一看下其他维度的用户属性。贷款目的分布中,debt_consolidation(债务合并)的数量最高,也就是借新还旧。其次是credit_card(还信用卡)。第三名是其他,第四名的是home_improvement(家装)。后面还有婚礼,医疗,教育和度假等等。贷款目的非常多元化。下面的这些
贷款目的是Lending Club整理并汇总后的信息。
lc['purpose'].value_counts()
再细一级的贷款目的内容就更加庞杂和有意思了。真的能感觉到美国人做什么事情都通过贷款来实现。
lc['title'].value_counts()
从信用等级分布来看,Lending Club中大部分用户为B和A级,G级用户数量较少。大部分用户都拥有较高的信用等级。
lc['grade'].value_counts()
数据表中的emp_title字段记录了用户的职位名称,简单的统计后发现贷款用户的职业分布非常广泛。其中排第一的是US Army。其次为Bank of America。后面还包括IBM,AT&T,UPS的用户。
lc['emp_title'].value_counts()
在工作年限上贷款用户的分布非常极端,数量排名第一的是工作10年以上,第二名是工作小于1年。第三名是工作2年。可见刚毕业的年轻人和30岁以上的人是贷款的主要人群。年轻人刚开始工作,欲望大于收入,需要贷款来实现需求。岁数大一些的人竞争力逐渐下降,负担变重,也需要靠贷款来周转。
lc['emp_length'].value_counts()
从贷款人的房屋情况来看,大部分用户在租房,其次排名第二的用户房屋进行了抵押贷款,自己拥有房屋的仅为3251人,排名第三。
lc['home_ownership'].value_counts()
从地域的分布来看排名第一个的是加利福尼亚州,第二是纽约州,第三是佛罗里达州 。对美国地理不太熟悉,不清楚为什么是这三个州的贷款用户数较高。据说Lending Club为了降低坏账率有一套投资人与贷款人的职能匹配系统,里面包含地理位置的匹配,我猜测也许这三个州的投资人较多吧。
lc['addr_state'].value_counts()
了解完贷款用户的属性后再来看下Lending Club产品。这里我们主要关注Lending Club的贷款利率和贷款期限情况。
从贷款利率的角度来看,Lending Club的贷款利率从5%到25%跨度较大,并且每个人的利率都不一样,即使同样借款金额和期限的两个贷款人,也可能有不同的贷款利率,这些利息是Lending Club对贷款人评估后计算出来的。粗略来看贷款利息依据用户的信用等级变化而变化,A级用户贷款利率低,D和E级或者更低的等
级用户贷款利率普遍较高。
lc['int_rate'].value_counts()
从贷款期限角度来看,Lending Club的贷款都为长期贷款,分为36个月和60个月两类。很难想象美国人借500美金还要分36个月还清贷款。
lc['term'].value_counts()
从饼图上可以更清楚的看到两类贷款期限的占比情况,约75%的贷款为36个月的,25%为60个月的期限。
labels = '36 months', '60 months ' colors = ['lightskyblue', 'lightcoral'] plt.pie(lc['term'].value_counts(),labels=labels,colors=colors,shadow=True,startangle=90) plt.show()
两个贷款期限对应的金额和笔数情况来看,60个月的贷款金额占比要高于笔数的占比,可见60个月中应该有一部分为大金额贷款。
lc.groupby('term')['loan_amnt','member_id'].agg(['count','sum'])
从运营的角度来分析,Lending Club的贷款都放给了那类用户,又从哪些用户身上获得了最多的利息收入呢?从用户信用等级维度下来看贷款与利息的对比。在贷款金额和笔数上Lending Club主要贷款给信用等级较高的客户,因此A,B,C三个等级的贷款用户无论是从获得的贷款笔数和金额上都是较高的,随着等级的下
降获得的贷款笔数和金额逐渐减少。而从收取的总利息上来看,Lending Club从中间和较低信用等级用户身上获得的利息收入要明显高于信用等级较高的用户。这也是Lending Club一贯的策略,对信用等级较差的人收取较高的利息来补偿可能的违约风险。这里需要说明的是Lending Club是的收益来自于收取贷款及投资
方的贷款交易的手续费和管理费,而并非息差。
以下是分等级贷款金额和利息收入金额笔数对比情况,具体代码如下:这里使用了分类汇总功能,将数据表中的loan_amnt和total_rec_int按grade维度进行汇总,并分别进行计数和求和。
lc.groupby('grade')['loan_amnt','total_rec_int'].agg(['count','sum'])
换个角度从贷款期限维度来分析,60个月的贷款笔数和金额明显小于36个月。但从获得的利息收入情况来看正好相反,Lending Club从60个月的贷款中获得的利息收入要明显高于36个月。贷款期限越长,对于投资人的风险越大,但相应的收益也越高。
以下是分期限贷款金额和利息收入金额及笔数对比情况,具体代码如下:这里同样使用了分类汇总功能。
lc.groupby('term')['loan_amnt','total_rec_int'].agg(['count','sum'])
从风险控制的角度分析,随着Lending Club贷款笔数的增长,Charged Off的数量也随之增加,以下是Charged Off的变化趋势图。
x=lc.loc[(lc["loan_status"]=="Charged Off")] x["loan_status"] x.groupby('issue_d').count() y=x.groupby('issue_d').count() plt.plot(y["loan_status"]) plt.show()
从贷款状态的角度分析,共有约6000笔贷款出现Charged Off的情况。另外还有20单在宽恕期限内还款,8笔贷款延迟半个月到1一个月还款,24比贷款延迟1-3个月还款。
以下是分贷款状态金额和笔数对比情况,具体代码如下:这里使用了类似Excel数据透视表的功能,行为贷款状态,数值为贷款的金额和笔数汇总值。
pd.pivot_table(lc,index=["loan_status"],values=["loan_amnt"],aggfunc=[np.sum,len])
在上面数据表的基础上增加用户信用等级维度再来看下,信用等级较高的用户Charged Off情况较少,信用等级低的用户由于获得贷款的笔数相对较低,所以看起来Charged Off的数量也较低,但占比却较高。
以下是分等级贷款状况金额和笔数对比的情况,具体代码如下:这里依然使用了类似Excel数据透视表的功能,在之前的基础上增加了列字段,并设定贷款用户等级为列字段的值。
pd.pivot_table(lc,index=["loan_status",],values=['loan_amnt'],columns=["grade"],aggfunc=[np.sum,len],fill_value=0)
再从贷款用途的维度来分析,Charged Off最高的是debt_consolidation(债务合并),也就是借新债还旧债的情况,这种属于风险较高的一种贷款目的。这是一种比较粗糙的推测结果,更准确的情况还需要看每类贷款目的自身Charged Off的比率情况才能准确判断。
以下是分贷款用途的贷款状况金额和笔数对比情况,具体代码如下:
pd.pivot_table(lc,index=["purpose"],values=["loan_amnt"],columns=["loan_status"],aggfunc=[len,np.sum],fill_value=0)
—【所有文章及图片版权归 蓝鲸(王彦平)所有。欢迎转载,但请注明转自“蓝鲸网站分析博客”。】—