python matplotlib 对12万条p2p逾期数据进行可视化分析

        北京互联网金融协会在今年公布了一份12万人的逾期名单,我花了两个小时爬下来了,(关注微信公众号淑芬和二狗,回复p2p,文末获取数据和代码下载链接),下面就简单的对数据做一下分析,正好也学习一下python matplotlib。首先读取数据,选取需要的字段,并对字段名称进行中文命名。身份证前六位对照表用于解析地址,后面会用到。

####读取数据
import pandas as pd
import numpy as np
data = pd.read_csv('ppData.csv')
file = open("身份证前六位对照表.txt",encoding='utf-8')
file_list = []
while 1:
    line = file.readline()
    if not line:
        break
    file_list.append(line.split(' '))
id_code = [ele[0] for ele in  file_list]
id_addr = [ele[1].split('\n')[0] for ele in  file_list]
id_dict = dict(zip(id_code,id_addr))

###选取所需要字段
use_col = ['beginOverdueTime','hasCollectionDesc',
       'idcardno', 'isLoss', 'name', 'overdue', 'phoneNo', 'platFormName',
       'province', 'totalLoanAmount']
use_col_chinese = ['开始逾期日期','是否催收','身份证号码','是否失联','姓名','逾期金额',
                   '手机号码','借贷平台','区域/城市','借贷金额']
data_use = data[use_col]
data_use.columns = use_col_chinese

        字段区域/城市的不是标准的省市地址,如重庆、重庆市,需要标注化为重庆市。直接处理这些比较繁琐,通过身份证号前六位可以解析出标准的前三级地址包括省、市、区县。

###解析身份证前六位 地址编码
def deal_id1(x):
    try:
        return id_dict[x['身份证号码'][:2]+'0000']
    except BaseException:
        return '空'
def deal_id2(x):
    try:
        return id_dict[x['身份证号码'][:4]+'00']
    except BaseException:
        return '空'
def deal_id3(x):
    try:
        return id_dict[x['身份证号码'][:6]]
    except BaseException:
        return '空'
data_use['一级地址'] = data_use.apply(lambda x:deal_id1(x),axis =1)
data_use['二级地址'] = data_use.apply(lambda x:deal_id2(x),axis =1)
data_use['三级地址'] = data_use.apply(lambda x:deal_id3(x),axis =1)

        120691条数据中,绝大部分是个人贷款,一小部分是企业贷款,我们只分析个人的数据。若是企业,身份证号码字段对应的企业的社会信用编码,通过该字段,滤除企业的数据。


def judge_ifCompay(x):
    if x['一级地址'] == '空'or len(x['身份证号码'])!=18:
        return '是'
    elif x['一级地址'] != '空' and len(x['身份证号码'])==18:
        return '否'
    else:
        return '未知'
data_use['是否企业'] = data_use.apply(lambda x:judge_ifCompay(x),axis = 1)
data_company = data_use[data_use['是否企业']=='是']
data_person = data_use[data_use['是否企业']=='否']

        通过身份证号出生日期计算年龄以及各个年龄的人的逾期人数、逾期总金额、借贷总金额,并画图。


###解析年龄 
def deal_age(x):
    try:
        tmp = 2019-int(x['身份证号码'][6:10])
        return tmp if (tmp>0 and tmp<100) else 30
    except BaseException:
        print(x['身份证号码'])
        return 2019-int('19'+x['身份证号码'][8:10])
data_person['年龄'] = data_person.apply(lambda x:deal_age(x),axis=1)
#年龄与逾期人数
data_age = data_person.groupby(['年龄']).apply(lambda x:x['身份证号码'].count()).reset_index(name = '人数')
#年龄与逾期总金额
sum_age = data_person.groupby(['年龄']).apply(lambda x:x['逾期金额'].sum()).reset_index(name = '逾期总金额')
#年龄与借贷总金额
sumload_age = data_person.groupby(['年龄']).apply(lambda x:x['借贷金额'].sum()).reset_index(name = '借贷总金额')

##画图
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
font = FontProperties(fname = "./chinese.simhei.ttf",size=15)
fig,axs = plt.subplots(3,1)

axs[0].plot(data_age['年龄'],data_age['人数'])
axs[0].set_xlim(15, 80)
#axs[0].set_xlabel('年龄')
axs[0].set_ylabel('逾期人数',fontproperties = font)
axs[0].grid(True)

axs[1].plot(sum_age['年龄'],sum_age['逾期总金额'])
axs[1].set_xlim(15, 80)
#axs[1].set_xlabel('年龄')
axs[1].set_ylabel('逾期总金额',fontproperties = font)
axs[1].grid(True)

axs[2].plot(sumload_age['年龄'],sumload_age['借贷总金额'])
axs[2].set_xlim(15, 80)
axs[2].set_xlabel('年龄',fontproperties = font)
axs[2].set_ylabel('借贷总金额',fontproperties = font)
axs[2].grid(True)
plt.savefig('年龄_人数_逾期金额_借贷总金额.jpg')
plt.show()

        从图中可以看到30-35的中年人已经开始油腻了,逾期人数较多。想想再过两年二狗也要快30了,就心疼地抱住了自己。下面按照地区分析逾期金额和未逾期金额,并给出柱状图。

###各个省市的未逾期总金额和逾期总金额
addr_num = data_person.groupby(['一级地址']).apply(lambda x:x['身份证号码'].count()).reset_index(name = '人数').sort_values(by=['人数'])
addr_sum_overdue = data_person.groupby(['一级地址']).apply(lambda x:x['逾期金额'].sum()).reset_index(name = '逾期总金额')
addr_sum_un_overdue = data_person.groupby(['一级地址']).apply(lambda x:x['借贷金额'].sum()-x['逾期金额'].sum()).reset_index(name = '未逾期总金额')
addr_sum_temp = addr_num.merge(addr_sum_overdue,how = 'left')
addr_sum_temp = addr_sum_temp.merge(addr_sum_un_overdue,how = 'left')
addr_sum_temp['借贷总金额'] = addr_sum_temp.apply(lambda x:x['逾期总金额']+x['未逾期总金额'],axis = 1)
addr_sum_temp['占比'] = addr_sum_temp.apply(lambda x:x['逾期总金额']/(x['逾期总金额']+x['未逾期总金额']),axis = 1)
addr_sum_temp = addr_sum_temp.sort_values(by=['借贷总金额'])

##画图
plt.rcParams['font.sans-serif'] = ['SimHei']
N = addr_sum_temp.shape[0]
menMeans = addr_sum_temp['逾期总金额'].values
womenMeans = addr_sum_temp['未逾期总金额'].values
ind = np.arange(N)
width = 0.35
plt.rcParams['figure.figsize'] = (8, 8.0)
p1 = plt.barh(ind, menMeans, width)
p2 = plt.barh(ind, womenMeans, width,left = menMeans)
plt.xlabel('金额',fontproperties = font)
plt.ylabel('地区',fontproperties = font)
plt.title('不同地区逾期金额和未逾期金额')
plt.yticks(ind, addr_sum_temp['一级地址'].values)
#plt.yticks(np.arange(0, 81, 10))
plt.legend((p1[0], p2[0]), ('逾期金额', '未逾期金额'))
plt.savefig('地区_逾期_未逾期柱状图.jpg')
plt.show()

        其中,按照逾期总金额与借贷总金额的比值降序排列的表格如下:

        下面分析不同地域逾期人数中失联和未失联人数,并给出柱状图。


addr_num = data_person.groupby(['一级地址']).apply(lambda x:x['身份证号码'].count()).reset_index(name = '人数').sort_values(by=['人数'])
data_peson_loss = data_person[data_person['是否失联']=='是']
addr_num_loss = data_peson_loss.groupby(['一级地址']).apply(lambda x:x['身份证号码'].count()).reset_index(name = '失联人数')
addr_num = addr_num.merge(addr_num_loss,how = 'left').fillna(0)
addr_num['未失联人数'] = addr_num.apply(lambda x:x['人数']-x['失联人数'],axis=1)
addr_num['失联占比'] = addr_num.apply(lambda x:x['失联人数']/x['人数'],axis=1)

N = addr_num.shape[0]
menMeans = addr_num['失联人数'].values
womenMeans = addr_num['未失联人数'].values
ind = np.arange(N)
width = 0.35
plt.rcParams['figure.figsize'] = (8, 8.0)
p1 = plt.barh(ind, menMeans, width)
p2 = plt.barh(ind, womenMeans, width,left = menMeans)
plt.xlabel('人数')
plt.ylabel('地区')
plt.title('不同地区失联人数和未失联人数')
plt.yticks(ind, addr_num['一级地址'].values)
#plt.yticks(np.arange(0, 81, 10))
plt.legend((p1[0], p2[0]), ('失联人数', '未失联人数'))
plt.savefig('地区_失联_未失联.jpg')
plt.show()

        其中,按照失联人数与逾期总人数的比值降序排列的表格如下:

        针对地域,我就给出分析的图表,其他的大家自己领悟吧。最后分析一下开始逾期时间和逾期人数的关系,逾期人数按月统计,并给出柱状图。


####逾期时间
ata_person1 = data_person[data_person['逾期年份'].values != ' 42,823.00 '] ##脏数据
data_person1['开始逾期日期'] = data_person1.apply(lambda x:x['开始逾期日期'].lstrip(),axis=1)
data_person1['开始逾期日期'] = data_person1.apply(lambda x:x['开始逾期日期'].replace('-','/'),axis=1)
data_person1['逾期年份'] = data_person1.apply(lambda x:x['开始逾期日期'].split('/')[0],axis=1)
data_person1 = data_person[data_person['逾期年份'].values != '42,823.00 ']
data_person1['逾期月份'] = data_person1.apply(lambda x:x['开始逾期日期'].split('/')[1],axis=1)
data_person1['逾期月份'] = data_person1.apply(lambda x:x['逾期月份'] if len(x['逾期月份'])==2 else '0'+x['逾期月份'],axis=1)
data_person1['逾期年月'] = data_person1.apply(lambda x:x['逾期年份']+x['逾期月份'],axis = 1)
time_data = data_person1.groupby(['逾期年月']).apply(lambda x:x['身份证号码'].count()).reset_index(name = '人数').sort_values(by=['逾期年月'])

##画图
import pylab as pl
fig,ax = plt.subplots()
ax.bar(time_data['逾期年月'].values, time_data['人数'].values)
#plt.xticks()
plt.xlabel('逾期年月',fontproperties = font)
plt.ylabel('人数',fontproperties = font)
plt.title('时间与逾期人数关系')
plt.xticks([i for i in range(time_data['逾期年月'].shape[0])])
pl.xticks(rotation=270)
plt.savefig('时间_人数柱状图.jpg')
plt.show()

        图中可以发现逾期集中在2018年下半年。关于借贷平台,12万条数据大部分来自于宜信,所以没有针对借贷平台做统计分析。

 

个人微信公众号:淑芬和二狗

 

 

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值