0


【大数据基础】基于信用卡逾期数据的Spark数据处理与分析

https://dblab.xmu.edu.cn/blog/2707/

实验过程

数据预处理

本次实验数据集来自和鲸社区的信用卡评分模型构建数据,以数据集cs-training.csv为分析主体,其中共有15万条记录,11列属性。
每个数据包含以下字段:
字段名称 字段含义 例子
(1)SeriousDlqin2yrs 是否逾期 0,1
(2)RevolvingUtilizationOfUnsecuredLines 信用卡和个人信贷额度的总余额 0.766126609
(3)Age 年龄 45,20,30
(4)NumberOfTime30-59DaysPastDueNotWorse 借款人逾期30-59天的次数 0,2,3
(5)DebtRatio 负债比率 0.802982129
(6)MonthlyIncome 月收入 9120,3000
(7)NumberOfOpenCreditLinesAndLoans 未偿还贷款数量 ,0,4,13
(8)NumberOfTimes90DaysLate 借款人逾期90天以上的次数 0,1,3
(9)NumberRealEstateLoansOrLines 房地产贷款的数量 3,6
(10)NumberOfTime60-89DaysPastDueNotWorse 借款人逾期60-89天的次数 0,3
(11)NumberOfDependents 家庭中的家属人数 0,1,3
在这里插入图片描述

本次实验采用pandas库对数据进行预处理。在实验中,不对信用卡和个人信贷额度的总余额、负债比率、未偿还贷款数量、逾期90天以上的次数这4个属性进行处理分析。
具体处理步骤如下:
(1)读取数据
(2)查看数据是否具有重复值,去除重复值
(3)查看各字段缺失率,缺失值以均值填充
(4)选取要研究的属性,删除不研究的属性
(5)保存文件到本地
使用代码文件data_preprocessing.py对数据预处理,运行data_preprocessing.py文件的步骤如下:

  1. import pandas as pd
  2. # 读取数据
  3. df = pd.read_csv("~/Desktop/cs-training.csv")# 去除重复值
  4. df.duplicated()
  5. df.drop_duplicates()# 查看各字段缺失率
  6. df.info()# 缺失值按均值填充for col inlist(df.columns[df.isnull().sum()>0]):
  7. mean_val = df[col].mean()
  8. df[col].fillna(mean_val, inplace=True)# 删除不分析的列
  9. columns =["RevolvingUtilizationOfUnsecuredLines","DebtRatio","NumberOfOpenCreditLinesAndLoans","NumberOfTimes90DaysLate"]
  10. df.drop(columns,axis=1,inplace=True)# 保存到本地
  11. df.to_csv("~/OverDue/data.csv")

在这里插入图片描述

将文件上传至HDFS文件系统

  1. # 启动Hadoop
  2. cd /usr/local/hadoop
  3. ./sbin/start-dfs.sh
  4. # 在HDFS文件系统中创建/OverDue目录./bin/hdfs dfs -mkdir /data
  5. # 上传文件到HDFS文件系统中./bin/hdfs dfs -put ~/OverDue/data.csv /OverDue/data.csv

在这里插入图片描述

使用Spark对数据处理分析

我们将采用Python编程语言和Spark大数据框架对数据集“data.csv”进行处理分析,具体步骤如下:
(1)读取HDFS文件系统中的数据文件,生成DataFrame
(2)修改列名
(3)本次信用卡逾期的总体统计
(4)年龄与本次信用卡逾期的结合统计
(5)两次逾期记录与本次信用卡逾期的结合统计
(6)房产抵押数量与本次信用卡逾期的结合统计
(7)家属人数与本次信用卡逾期的结合统计
(8)月收入与本次信用卡逾期的结合统计
(9)将统计数据返回给数据可视化文件data_web.py

  1. ./bin/hdfs dfs -put ~/OverDue/data1.csv /user/hadoop

代码文件data_analysis.py的内容如下:

  1. from pyspark.sql import SparkSession
  2. from pyspark import SparkContext,SparkConf
  3. from pyspark.sql import Row
  4. from pyspark.sql.types import*from pyspark.sql import functions
  5. defanalyse(filename):# 读取数据
  6. spark = SparkSession.builder.config(conf = SparkConf()).getOrCreate()
  7. df = spark.read.format("csv").option("header","true").load(filename)# 修改列名
  8. df = df.withColumnRenamed('SeriousDlqin2yrs','y')
  9. df = df.withColumnRenamed('NumberOfTime30-59DaysPastDueNotWorse','30-59days')
  10. df = df.withColumnRenamed('NumberOfTime60-89DaysPastDueNotWorse','60-89days')
  11. df = df.withColumnRenamed('NumberRealEstateLoansOrLines','RealEstateLoans')
  12. df = df.withColumnRenamed('NumberOfDependents','families')# 返回data_web.py的数据列表
  13. all_list =[]# 本次信用卡逾期分析# 共有逾期10026人,139974没有逾期,总人数150000
  14. total_y =[]for i inrange(2):
  15. total_y.append(df.filter(df['y']== i).count())
  16. all_list.append(total_y)# 年龄分析
  17. df_age = df.select(df['age'],df['y'])
  18. agenum =[]bin=[0,30,45,60,75,100]# 统计各个年龄段的人口for i inrange(5):
  19. agenum.append(df_age.filter(df['age'].between(bin[i],bin[i+1])).count())
  20. all_list.append(agenum)# 统计各个年龄段逾期与不逾期的数量
  21. age_y =[]for i inrange(5):
  22. y0 = df_age.filter(df['age'].between(bin[i],bin[i+1])).\
  23. filter(df['y']=='0').count()
  24. y1 = df_age.filter(df['age'].between(bin[i],bin[i+1])).\
  25. filter(df['y']=='1').count()
  26. age_y.append([y0,y1])
  27. all_list.append(age_y)# 有逾期记录的人的本次信用卡逾期数量
  28. df_pastDue = df.select(df['30-59days'],df['60-89days'],df['y'])# 30-5923982人,4985逾期,18997不逾期
  29. numofpastdue =[]
  30. numofpastdue.append(df_pastDue.filter(df_pastDue['30-59days']>0).count())
  31. y_numofpast1 =[]for i inrange(2):
  32. x = df_pastDue.filter(df_pastDue['30-59days']>0).\
  33. filter(df_pastDue['y']== i).count()
  34. y_numofpast1.append(x)# 60-897604人,2770逾期,4834不逾期
  35. numofpastdue.append(df_pastDue.filter(df_pastDue['60-89days']>0).count())
  36. y_numofpast2 =[]for i inrange(2):
  37. x = df_pastDue.filter(df_pastDue['60-89days']>0).\
  38. filter(df_pastDue['y']== i).count()
  39. y_numofpast2.append(x)# 两个记录都有的人有4393人,逾期1907,不逾期2486
  40. numofpastdue.append(df_pastDue.filter(df_pastDue['30-59days']>0).filter(df_pastDue['60-89days']>0).count())
  41. y_numofpast3 =[]for i inrange(2):
  42. x = df_pastDue.filter(df_pastDue['30-59days']>0).\
  43. filter(df_pastDue['60-89days']>0).filter(df_pastDue['y']== i).count()
  44. y_numofpast3.append(x)
  45. all_list.append(numofpastdue)
  46. all_list.append(y_numofpast1)
  47. all_list.append(y_numofpast2)
  48. all_list.append(y_numofpast3)# 房产抵押数量分析
  49. df_Loans = df.select(df['RealEstateLoans'],df['y'])# 有无抵押房产人数情况
  50. numofrealandnoreal =[]
  51. numofrealandnoreal.append(df_Loans.filter(df_Loans['RealEstateLoans']==0).count())
  52. numofrealandnoreal.append(df_Loans.filter(df_Loans['RealEstateLoans']>0).count())
  53. all_list.append(numofrealandnoreal)## 房产无抵押共有56188人,逾期4672人,没逾期51516
  54. norealnum =[]for i inrange(2):
  55. x = df_Loans.filter(df_Loans['RealEstateLoans']==0).\
  56. filter(df_Loans['y']== i).count()
  57. norealnum.append(x)
  58. all_list.append(norealnum)# 房产抵押共有93812人,逾期5354人,不逾期88458
  59. realnum =[]for i inrange(2):
  60. x = df_Loans.filter(df_Loans['RealEstateLoans']>0).\
  61. filter(df_Loans['y']== i).count()
  62. realnum.append(x)
  63. all_list.append(realnum)# 家属人数分析
  64. df_families = df.select(df['families'],df['y'])# 有无家属人数统计
  65. nofamiliesAndfamilies =[]
  66. nofamiliesAndfamilies.append(df_families.filter(df_families['families']>0).count())
  67. nofamiliesAndfamilies.append(df_families.filter(df_families['families']==0).count())
  68. all_list.append(nofamiliesAndfamilies)# 有家属59174人,逾期4752人,没逾期54422
  69. y_families =[]
  70. y_families.append(df_families.filter(df_families['families']>0).filter(df_families['y']==0).count())
  71. y_families.append(df_families.filter(df_families['families']>0).filter(df_families['y']==1).count())
  72. all_list.append(y_families)# 没家属90826人,逾期5274人,没逾期85552
  73. y_nofamilies =[]
  74. y_nofamilies.append(df_families.filter(df_families['families']==0).filter(df_families['y']==0).count())
  75. y_nofamilies.append(df_families.filter(df_families['families']==0).filter(df_families['y']==1).count())
  76. all_list.append(y_nofamilies)# 月收入分析
  77. df_income = df.select(df['MonthlyIncome'],df['y'])# 获取平均值,其中先返回Row对象,再获取其中均值
  78. mean_income = df_income.agg(functions.avg(df_income['MonthlyIncome'])).head()[0]# 收入分布,105854人没超过均值667044146人超过均值6670
  79. numofMeanincome =[]
  80. numofMeanincome.append(df_income.filter(df['MonthlyIncome']< mean_income).count())
  81. numofMeanincome.append(df_income.filter(df['MonthlyIncome']> mean_income).count())
  82. all_list.append(numofMeanincome)# 未超过均值的逾期情况分析,97977人没逾期,7877人逾期
  83. y_NoMeanIncome =[]
  84. y_NoMeanIncome.append(df_income.filter(df['MonthlyIncome']< mean_income).filter(df['y']==0).count())
  85. y_NoMeanIncome.append(df_income.filter(df['MonthlyIncome']< mean_income).filter(df['y']==1).count())
  86. all_list.append(y_NoMeanIncome)# 超过均值的逾期情况分析,41997人没逾期,2149人逾期
  87. y_MeanIncome =[]
  88. y_MeanIncome.append(df_income.filter(df['MonthlyIncome']> mean_income).filter(df['y']==0).count())
  89. y_MeanIncome.append(df_income.filter(df['MonthlyIncome']> mean_income).filter(df['y']==1).count())
  90. all_list.append(y_MeanIncome)# 数据可视化data_web.pyreturn all_list

数据可视化

选择使用python第三方库pyecharts作为可视化工具,其中pyecharts版本为1.7.0。采用其中的柱状图和饼图来详细展现分析结果。
代码文件data_web.py的内容如下:

  1. from pyecharts.charts import Bar
  2. from pyecharts.charts import Pie
  3. from pyecharts.charts import Page
  4. from pyecharts import options as opts
  5. import data_analysis
  6. # --------总体逾期人数情况--------------defdraw_total(total_list):
  7. attr =["未逾期人数","逾期人数"]
  8. pie =(
  9. Pie().add("总体逾期人数",[list(z)for z inzip(attr,total_list)]).set_global_opts(title_opts=opts.TitleOpts(title="总体逾期人数分布")).set_series_opts(
  10. tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)"),
  11. label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)")))return pie
  12. # --------年龄与逾期人数情况--------------defdraw_age(age_list,y_ageList):
  13. total_pie = draw_total(all_list[0])
  14. attr =["0-30","30-45","45-60","60-75","75-100"]
  15. y0_agenum =[]
  16. y1_agenum =[]for i inrange(5):
  17. y0_agenum.append(y_ageList[i][0])
  18. y1_agenum.append(y_ageList[i][1])
  19. bar =(
  20. Bar().add_xaxis(attr).add_yaxis("人数分布", age_list).add_yaxis("未逾期人数分布", y0_agenum).add_yaxis("逾期人数分布", y1_agenum).set_global_opts(title_opts=opts.TitleOpts(title="各年龄段逾期情况")))
  21. attr =["未逾期","逾期"]
  22. pie1 =(
  23. Pie().add("0-30年龄段",[list(z)for z inzip(attr,y_ageList[0])]).set_global_opts(title_opts=opts.TitleOpts(title="0-30年龄段逾期情况")).set_series_opts(
  24. tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)"),
  25. label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)")))
  26. pie2 =(
  27. Pie().add("30-45年龄段",[list(z)for z inzip(attr,y_ageList[1])]).set_global_opts(title_opts=opts.TitleOpts(title="30-45年龄段逾期情况")).set_series_opts(
  28. tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)"),
  29. label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)")))
  30. pie3 =(
  31. Pie().add("45-60年龄段",[list(z)for z inzip(attr,y_ageList[2])]).set_global_opts(title_opts=opts.TitleOpts(title="45-60年龄段逾期情况")).set_series_opts(
  32. tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)"),
  33. label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)")))
  34. pie4 =(
  35. Pie().add("60-75年龄段",[list(z)for z inzip(attr,y_ageList[3])]).set_global_opts(title_opts=opts.TitleOpts(title="60-75年龄段逾期情况")).set_series_opts(
  36. tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)"),
  37. label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)")))
  38. pie5 =(
  39. Pie().add("75-100年龄段",[list(z)for z inzip(attr,y_ageList[4])]).set_global_opts(title_opts=opts.TitleOpts(title="75-100年龄段逾期情况")).set_series_opts(
  40. tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)"),
  41. label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)")))
  42. page = Page()
  43. page.add(bar)
  44. page.add(total_pie)
  45. page.add(pie1)
  46. page.add(pie2)
  47. page.add(pie3)
  48. page.add(pie4)
  49. page.add(pie5)
  50. page.render('age_OverDue.html')# --------逾期记录与逾期人数情况--------------defdraw_pastdue(numofpastdue,pastdue1num,pastdue2num,pastdue12num):
  51. total_pie = draw_total(all_list[0])
  52. attr =["有30-59days逾期记录的人数","有60-89days逾期记录的人数","有长短期逾期记录的人数"]
  53. bar =(
  54. Bar().add_xaxis(attr).add_yaxis("人数", numofpastdue).set_global_opts(title_opts=opts.TitleOpts(title="有逾期记录的人数")))
  55. attr =["未逾期","逾期"]
  56. pie1 =(
  57. Pie().add("有短期逾期记录的人的逾期情况",[list(z)for z inzip(attr,pastdue1num)]).set_global_opts(title_opts=opts.TitleOpts(title="有短期逾期记录的人的逾期情况")).set_series_opts(
  58. tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)"),
  59. label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)")))
  60. pie2 =(
  61. Pie().add("有长期逾期记录的人的逾期情况",[list(z)for z inzip(attr,pastdue2num)]).set_global_opts(title_opts=opts.TitleOpts(title="有长期逾期记录的人的逾期情况")).set_series_opts(
  62. tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)"),
  63. label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)")))
  64. pie3 =(
  65. Pie().add("长短期逾期记录都有的人的逾期情况",[list(z)for z inzip(attr,pastdue12num)]).set_global_opts(title_opts=opts.TitleOpts(title="长短期逾期记录都有的人的逾期情况")).set_series_opts(
  66. tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)"),
  67. label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)")))
  68. page = Page()
  69. page.add(bar)
  70. page.add(total_pie)
  71. page.add(pie1)
  72. page.add(pie2)
  73. page.add(pie3)
  74. page.render('pastDue_OverDue.html')# --------房产抵押与逾期人数情况--------------defdraw_realestateLoans(numofrealornoreal,y_norealnum,y_realnum):
  75. total_pie = draw_total(all_list[0])
  76. attr =["无房产抵押人数","有房产抵押人数"]
  77. bar =(
  78. Bar().add_xaxis(attr).add_yaxis("人数", numofrealornoreal).set_global_opts(title_opts=opts.TitleOpts(title="房产抵押人数分布")))
  79. attr =["未逾期","逾期"]
  80. pie1 =(
  81. Pie().add("无房产抵押的人的逾期情况",[list(z)for z inzip(attr,y_norealnum)]).set_global_opts(title_opts=opts.TitleOpts(title="无房产抵押的人的逾期情况")).set_series_opts(
  82. tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)"),
  83. label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)")))
  84. pie2 =(
  85. Pie().add("有房产抵押的人的逾期情况",[list(z)for z inzip(attr,y_realnum)]).set_global_opts(title_opts=opts.TitleOpts(title="有房产抵押的人的逾期情况")).set_series_opts(
  86. tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)"),
  87. label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)")))
  88. page = Page()
  89. page.add(bar)
  90. page.add(total_pie)
  91. page.add(pie1)
  92. page.add(pie2)
  93. page.render('realestateLoans_OverDue.html')# --------家属人数与逾期人数情况--------------defdraw_families(nofamiliesAndfamilies,y_families,y_nofamilies):
  94. total_pie = draw_total(all_list[0])
  95. attr =["有家属人数","无家属人数"]
  96. bar =(
  97. Bar().add_xaxis(attr).add_yaxis("人数", nofamiliesAndfamilies).set_global_opts(title_opts=opts.TitleOpts(title="有无家属人数分布")))
  98. attr =["未逾期","逾期"]
  99. pie1 =(
  100. Pie().add("无家属的人的逾期情况",[list(z)for z inzip(attr,y_nofamilies)]).set_global_opts(title_opts=opts.TitleOpts(title="无家属的人的逾期情况")).set_series_opts(
  101. tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)"),
  102. label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)")))
  103. pie2 =(
  104. Pie().add("有家属的人的逾期情况",[list(z)for z inzip(attr,y_families)]).set_global_opts(title_opts=opts.TitleOpts(title="有家属的人的逾期情况")).set_series_opts(
  105. tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)"),
  106. label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)")))
  107. page = Page()
  108. page.add(bar)
  109. page.add(total_pie)
  110. page.add(pie1)
  111. page.add(pie2)
  112. page.render('families_OverDue.html')# --------月收入与逾期人数情况--------------defdraw_income(numofMeanincome,y_NoMeanIncome,y_MeanIncome):
  113. total_pie = draw_total(all_list[0])
  114. attr =["未超过均值收入人数","超过均值收入人数"]
  115. bar =(
  116. Bar().add_xaxis(attr).add_yaxis("人数", numofMeanincome).set_global_opts(title_opts=opts.TitleOpts(title="有无超过均值收入人数分布")))
  117. attr =["未逾期","逾期"]
  118. pie1 =(
  119. Pie().add("未超过均值收入的人的逾期情况",[list(z)for z inzip(attr,y_NoMeanIncome)]).set_global_opts(title_opts=opts.TitleOpts(title="未超过均值收入的人的逾期情况")).set_series_opts(
  120. tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)"),
  121. label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)")))
  122. pie2 =(
  123. Pie().add("超过均值收入的人的逾期情况",[list(z)for z inzip(attr,y_MeanIncome)]).set_global_opts(title_opts=opts.TitleOpts(title="超过均值收入的人的逾期情况")).set_series_opts(
  124. tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)"),
  125. label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)")))
  126. page = Page()
  127. page.add(bar)
  128. page.add(total_pie)
  129. page.add(pie1)
  130. page.add(pie2)
  131. page.render('meanIncome_OverDue.html')if __name__ =='__main__':print("开始总程序")
  132. Filename ="/OverDue/data.csv"
  133. all_list = data_analysis.analyse(Filename)# 年龄与是否逾期情况
  134. draw_age(all_list[1],all_list[2])# 有无逾期记录与是否逾期情况
  135. draw_pastdue(all_list[3],all_list[4],all_list[5],all_list[6])# 房产抵押数量与是否逾期情况
  136. draw_realestateLoans(all_list[7],all_list[8],all_list[9])# 家属人数与是否逾期情况
  137. draw_families(all_list[10],all_list[11],all_list[12])# 月收入与是否逾期情况
  138. draw_income(all_list[13],all_list[14],all_list[15])print("结束总程序")

完整代码

  1. from pyspark.sql import SparkSession
  2. from pyspark import SparkContext,SparkConf
  3. from pyspark.sql import Row
  4. from pyspark.sql.types import*from pyspark.sql import functions
  5. defanalyse(filename):# 读取数据
  6. spark = SparkSession.builder.config(conf = SparkConf()).getOrCreate()
  7. df = spark.read.format("csv").option("header","true").load(filename)# 修改列名
  8. df = df.withColumnRenamed('SeriousDlqin2yrs','y')
  9. df = df.withColumnRenamed('NumberOfTime30-59DaysPastDueNotWorse','30-59days')
  10. df = df.withColumnRenamed('NumberOfTime60-89DaysPastDueNotWorse','60-89days')
  11. df = df.withColumnRenamed('NumberRealEstateLoansOrLines','RealEstateLoans')
  12. df = df.withColumnRenamed('NumberOfDependents','families')# 返回data_web.py的数据列表
  13. all_list =[]# 本次信用卡逾期分析# 共有逾期10026人,139974没有逾期,总人数150000
  14. total_y =[]for i inrange(2):
  15. total_y.append(df.filter(df['y']== i).count())
  16. all_list.append(total_y)# 年龄分析
  17. df_age = df.select(df['age'],df['y'])
  18. agenum =[]bin=[0,30,45,60,75,100]# 统计各个年龄段的人口for i inrange(5):
  19. agenum.append(df_age.filter(df['age'].between(bin[i],bin[i+1])).count())
  20. all_list.append(agenum)# 统计各个年龄段逾期与不逾期的数量
  21. age_y =[]for i inrange(5):
  22. y0 = df_age.filter(df['age'].between(bin[i],bin[i+1])).\
  23. filter(df['y']=='0').count()
  24. y1 = df_age.filter(df['age'].between(bin[i],bin[i+1])).\
  25. filter(df['y']=='1').count()
  26. age_y.append([y0,y1])
  27. all_list.append(age_y)# 有逾期记录的人的本次信用卡逾期数量
  28. df_pastDue = df.select(df['30-59days'],df['60-89days'],df['y'])# 30-5923982人,4985逾期,18997不逾期
  29. numofpastdue =[]
  30. numofpastdue.append(df_pastDue.filter(df_pastDue['30-59days']>0).count())
  31. y_numofpast1 =[]for i inrange(2):
  32. x = df_pastDue.filter(df_pastDue['30-59days']>0).\
  33. filter(df_pastDue['y']== i).count()
  34. y_numofpast1.append(x)# 60-897604人,2770逾期,4834不逾期
  35. numofpastdue.append(df_pastDue.filter(df_pastDue['60-89days']>0).count())
  36. y_numofpast2 =[]for i inrange(2):
  37. x = df_pastDue.filter(df_pastDue['60-89days']>0).\
  38. filter(df_pastDue['y']== i).count()
  39. y_numofpast2.append(x)# 两个记录都有的人有4393人,逾期1907,不逾期2486
  40. numofpastdue.append(df_pastDue.filter(df_pastDue['30-59days']>0).filter(df_pastDue['60-89days']>0).count())
  41. y_numofpast3 =[]for i inrange(2):
  42. x = df_pastDue.filter(df_pastDue['30-59days']>0).\
  43. filter(df_pastDue['60-89days']>0).filter(df_pastDue['y']== i).count()
  44. y_numofpast3.append(x)
  45. all_list.append(numofpastdue)
  46. all_list.append(y_numofpast1)
  47. all_list.append(y_numofpast2)
  48. all_list.append(y_numofpast3)# 房产抵押数量分析
  49. df_Loans = df.select(df['RealEstateLoans'],df['y'])# 有无抵押房产人数情况
  50. numofrealandnoreal =[]
  51. numofrealandnoreal.append(df_Loans.filter(df_Loans['RealEstateLoans']==0).count())
  52. numofrealandnoreal.append(df_Loans.filter(df_Loans['RealEstateLoans']>0).count())
  53. all_list.append(numofrealandnoreal)## 房产无抵押共有56188人,逾期4672人,没逾期51516
  54. norealnum =[]for i inrange(2):
  55. x = df_Loans.filter(df_Loans['RealEstateLoans']==0).\
  56. filter(df_Loans['y']== i).count()
  57. norealnum.append(x)
  58. all_list.append(norealnum)# 房产抵押共有93812人,逾期5354人,不逾期88458
  59. realnum =[]for i inrange(2):
  60. x = df_Loans.filter(df_Loans['RealEstateLoans']>0).\
  61. filter(df_Loans['y']== i).count()
  62. realnum.append(x)
  63. all_list.append(realnum)# 家属人数分析
  64. df_families = df.select(df['families'],df['y'])# 有无家属人数统计
  65. nofamiliesAndfamilies =[]
  66. nofamiliesAndfamilies.append(df_families.filter(df_families['families']>0).count())
  67. nofamiliesAndfamilies.append(df_families.filter(df_families['families']==0).count())
  68. all_list.append(nofamiliesAndfamilies)# 有家属59174人,逾期4752人,没逾期54422
  69. y_families =[]
  70. y_families.append(df_families.filter(df_families['families']>0).filter(df_families['y']==0).count())
  71. y_families.append(df_families.filter(df_families['families']>0).filter(df_families['y']==1).count())
  72. all_list.append(y_families)# 没家属90826人,逾期5274人,没逾期85552
  73. y_nofamilies =[]
  74. y_nofamilies.append(df_families.filter(df_families['families']==0).filter(df_families['y']==0).count())
  75. y_nofamilies.append(df_families.filter(df_families['families']==0).filter(df_families['y']==1).count())
  76. all_list.append(y_nofamilies)# 月收入分析
  77. df_income = df.select(df['MonthlyIncome'],df['y'])# 获取平均值,其中先返回Row对象,再获取其中均值
  78. mean_income = df_income.agg(functions.avg(df_income['MonthlyIncome'])).head()[0]# 收入分布,105854人没超过均值667044146人超过均值6670
  79. numofMeanincome =[]
  80. numofMeanincome.append(df_income.filter(df['MonthlyIncome']< mean_income).count())
  81. numofMeanincome.append(df_income.filter(df['MonthlyIncome']> mean_income).count())
  82. all_list.append(numofMeanincome)# 未超过均值的逾期情况分析,97977人没逾期,7877人逾期
  83. y_NoMeanIncome =[]
  84. y_NoMeanIncome.append(df_income.filter(df['MonthlyIncome']< mean_income).filter(df['y']==0).count())
  85. y_NoMeanIncome.append(df_income.filter(df['MonthlyIncome']< mean_income).filter(df['y']==1).count())
  86. all_list.append(y_NoMeanIncome)# 超过均值的逾期情况分析,41997人没逾期,2149人逾期
  87. y_MeanIncome =[]
  88. y_MeanIncome.append(df_income.filter(df['MonthlyIncome']> mean_income).filter(df['y']==0).count())
  89. y_MeanIncome.append(df_income.filter(df['MonthlyIncome']> mean_income).filter(df['y']==1).count())
  90. all_list.append(y_MeanIncome)# 数据可视化data_web.pyreturn all_list
  91. from pyecharts.charts import Bar
  92. from pyecharts.charts import Pie
  93. from pyecharts.charts import Page
  94. from pyecharts import options as opts
  95. # --------总体逾期人数情况--------------defdraw_total(total_list):
  96. attr =["未逾期人数","逾期人数"]
  97. pie =(
  98. Pie().add("总体逾期人数",[list(z)for z inzip(attr,total_list)]).set_global_opts(title_opts=opts.TitleOpts(title="总体逾期人数分布")).set_series_opts(
  99. tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)"),
  100. label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)")))return pie
  101. # --------年龄与逾期人数情况--------------defdraw_age(age_list,y_ageList):
  102. total_pie = draw_total(all_list[0])
  103. attr =["0-30","30-45","45-60","60-75","75-100"]
  104. y0_agenum =[]
  105. y1_agenum =[]for i inrange(5):
  106. y0_agenum.append(y_ageList[i][0])
  107. y1_agenum.append(y_ageList[i][1])
  108. bar =(
  109. Bar().add_xaxis(attr).add_yaxis("人数分布", age_list).add_yaxis("未逾期人数分布", y0_agenum).add_yaxis("逾期人数分布", y1_agenum).set_global_opts(title_opts=opts.TitleOpts(title="各年龄段逾期情况")))
  110. attr =["未逾期","逾期"]
  111. pie1 =(
  112. Pie().add("0-30年龄段",[list(z)for z inzip(attr,y_ageList[0])]).set_global_opts(title_opts=opts.TitleOpts(title="0-30年龄段逾期情况")).set_series_opts(
  113. tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)"),
  114. label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)")))
  115. pie2 =(
  116. Pie().add("30-45年龄段",[list(z)for z inzip(attr,y_ageList[1])]).set_global_opts(title_opts=opts.TitleOpts(title="30-45年龄段逾期情况")).set_series_opts(
  117. tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)"),
  118. label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)")))
  119. pie3 =(
  120. Pie().add("45-60年龄段",[list(z)for z inzip(attr,y_ageList[2])]).set_global_opts(title_opts=opts.TitleOpts(title="45-60年龄段逾期情况")).set_series_opts(
  121. tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)"),
  122. label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)")))
  123. pie4 =(
  124. Pie().add("60-75年龄段",[list(z)for z inzip(attr,y_ageList[3])]).set_global_opts(title_opts=opts.TitleOpts(title="60-75年龄段逾期情况")).set_series_opts(
  125. tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)"),
  126. label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)")))
  127. pie5 =(
  128. Pie().add("75-100年龄段",[list(z)for z inzip(attr,y_ageList[4])]).set_global_opts(title_opts=opts.TitleOpts(title="75-100年龄段逾期情况")).set_series_opts(
  129. tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)"),
  130. label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)")))
  131. page = Page()
  132. page.add(bar)
  133. page.add(total_pie)
  134. page.add(pie1)
  135. page.add(pie2)
  136. page.add(pie3)
  137. page.add(pie4)
  138. page.add(pie5)
  139. page.render('age_OverDue.html')# --------逾期记录与逾期人数情况--------------defdraw_pastdue(numofpastdue,pastdue1num,pastdue2num,pastdue12num):
  140. total_pie = draw_total(all_list[0])
  141. attr =["有30-59days逾期记录的人数","有60-89days逾期记录的人数","有长短期逾期记录的人数"]
  142. bar =(
  143. Bar().add_xaxis(attr).add_yaxis("人数", numofpastdue).set_global_opts(title_opts=opts.TitleOpts(title="有逾期记录的人数")))
  144. attr =["未逾期","逾期"]
  145. pie1 =(
  146. Pie().add("有短期逾期记录的人的逾期情况",[list(z)for z inzip(attr,pastdue1num)]).set_global_opts(title_opts=opts.TitleOpts(title="有短期逾期记录的人的逾期情况")).set_series_opts(
  147. tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)"),
  148. label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)")))
  149. pie2 =(
  150. Pie().add("有长期逾期记录的人的逾期情况",[list(z)for z inzip(attr,pastdue2num)]).set_global_opts(title_opts=opts.TitleOpts(title="有长期逾期记录的人的逾期情况")).set_series_opts(
  151. tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)"),
  152. label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)")))
  153. pie3 =(
  154. Pie().add("长短期逾期记录都有的人的逾期情况",[list(z)for z inzip(attr,pastdue12num)]).set_global_opts(title_opts=opts.TitleOpts(title="长短期逾期记录都有的人的逾期情况")).set_series_opts(
  155. tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)"),
  156. label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)")))
  157. page = Page()
  158. page.add(bar)
  159. page.add(total_pie)
  160. page.add(pie1)
  161. page.add(pie2)
  162. page.add(pie3)
  163. page.render('pastDue_OverDue.html')# --------房产抵押与逾期人数情况--------------defdraw_realestateLoans(numofrealornoreal,y_norealnum,y_realnum):
  164. total_pie = draw_total(all_list[0])
  165. attr =["无房产抵押人数","有房产抵押人数"]
  166. bar =(
  167. Bar().add_xaxis(attr).add_yaxis("人数", numofrealornoreal).set_global_opts(title_opts=opts.TitleOpts(title="房产抵押人数分布")))
  168. attr =["未逾期","逾期"]
  169. pie1 =(
  170. Pie().add("无房产抵押的人的逾期情况",[list(z)for z inzip(attr,y_norealnum)]).set_global_opts(title_opts=opts.TitleOpts(title="无房产抵押的人的逾期情况")).set_series_opts(
  171. tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)"),
  172. label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)")))
  173. pie2 =(
  174. Pie().add("有房产抵押的人的逾期情况",[list(z)for z inzip(attr,y_realnum)]).set_global_opts(title_opts=opts.TitleOpts(title="有房产抵押的人的逾期情况")).set_series_opts(
  175. tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)"),
  176. label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)")))
  177. page = Page()
  178. page.add(bar)
  179. page.add(total_pie)
  180. page.add(pie1)
  181. page.add(pie2)
  182. page.render('realestateLoans_OverDue.html')# --------家属人数与逾期人数情况--------------defdraw_families(nofamiliesAndfamilies,y_families,y_nofamilies):
  183. total_pie = draw_total(all_list[0])
  184. attr =["有家属人数","无家属人数"]
  185. bar =(
  186. Bar().add_xaxis(attr).add_yaxis("人数", nofamiliesAndfamilies).set_global_opts(title_opts=opts.TitleOpts(title="有无家属人数分布")))
  187. attr =["未逾期","逾期"]
  188. pie1 =(
  189. Pie().add("无家属的人的逾期情况",[list(z)for z inzip(attr,y_nofamilies)]).set_global_opts(title_opts=opts.TitleOpts(title="无家属的人的逾期情况")).set_series_opts(
  190. tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)"),
  191. label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)")))
  192. pie2 =(
  193. Pie().add("有家属的人的逾期情况",[list(z)for z inzip(attr,y_families)]).set_global_opts(title_opts=opts.TitleOpts(title="有家属的人的逾期情况")).set_series_opts(
  194. tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)"),
  195. label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)")))
  196. page = Page()
  197. page.add(bar)
  198. page.add(total_pie)
  199. page.add(pie1)
  200. page.add(pie2)
  201. page.render('families_OverDue.html')# --------月收入与逾期人数情况--------------defdraw_income(numofMeanincome,y_NoMeanIncome,y_MeanIncome):
  202. total_pie = draw_total(all_list[0])
  203. attr =["未超过均值收入人数","超过均值收入人数"]
  204. bar =(
  205. Bar().add_xaxis(attr).add_yaxis("人数", numofMeanincome).set_global_opts(title_opts=opts.TitleOpts(title="有无超过均值收入人数分布")))
  206. attr =["未逾期","逾期"]
  207. pie1 =(
  208. Pie().add("未超过均值收入的人的逾期情况",[list(z)for z inzip(attr,y_NoMeanIncome)]).set_global_opts(title_opts=opts.TitleOpts(title="未超过均值收入的人的逾期情况")).set_series_opts(
  209. tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)"),
  210. label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)")))
  211. pie2 =(
  212. Pie().add("超过均值收入的人的逾期情况",[list(z)for z inzip(attr,y_MeanIncome)]).set_global_opts(title_opts=opts.TitleOpts(title="超过均值收入的人的逾期情况")).set_series_opts(
  213. tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)"),
  214. label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)")))
  215. page = Page()
  216. page.add(bar)
  217. page.add(total_pie)
  218. page.add(pie1)
  219. page.add(pie2)
  220. page.render('meanIncome_OverDue.html')if __name__ =='__main__':print("开始总程序")
  221. Filename ="hdfs://localhost:8020/user/hadoop/data1.csv"
  222. all_list = analyse(Filename)# 年龄与是否逾期情况
  223. draw_age(all_list[1],all_list[2])# 有无逾期记录与是否逾期情况
  224. draw_pastdue(all_list[3],all_list[4],all_list[5],all_list[6])# 房产抵押数量与是否逾期情况
  225. draw_realestateLoans(all_list[7],all_list[8],all_list[9])# 家属人数与是否逾期情况
  226. draw_families(all_list[10],all_list[11],all_list[12])# 月收入与是否逾期情况
  227. draw_income(all_list[13],all_list[14],all_list[15])print("结束总程序")

在这里插入图片描述
运行结果如下:(带overdue.html的文件)

在这里插入图片描述

数据可视化结果

  1. # 进入OverDue目录
  2. cd ~/OverDue
  3. # 提交data_web.py文件到spark-submit/usr/local/spark/bin/spark-submit --master local ~/OverDue/data_web.py

家属人数

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

逾期记录

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

房产抵押数量

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

月收入

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述### 总体
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

年龄

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

标签: 大数据 spark hadoop

本文转载自: https://blog.csdn.net/Algernon98/article/details/130051632
版权归原作者 仿生程序员会梦见电子羊吗 所有, 如有侵权,请联系我们删除。

“【大数据基础】基于信用卡逾期数据的Spark数据处理与分析”的评论:

还没有评论