123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- import consts
- import numpy as np;# 近3月开户最高贷款本金
- import utils
- import time;
- # 从“贷款信息”中提取,剔除“账户状态”为结清、转出、呆账、呆帐后,各笔贷款按转换为数字后的“24个月(账户)还款状态”的后3位数字中,取最大值即为该账户的近3月最大逾期期数数,然后max(每个账户的近3月最大逾期数)
- # 例如记录1最后3位数为136,记录2最后3位数为135;则近3月最大逾期期数数=6
- # “24个月(账户)还款状态”
- # 还款记录按日期排序最近3笔的最大逾期期数 TODO 规则可能会变
- def getPayRcdMaxOverdueNum(payRcdDf,month):
- # dateStr = utils.getLastMonthDate("",month)
- payRcdDf = payRcdDf.sort_values(by=["账户编号","还款日期"] , ascending=(True,False))
- payRcdDf = payRcdDf.groupby(['账户编号']).head(month)
- payRcdDf = payRcdDf[payRcdDf['还款状态']>0]
- payRcdTimesDf = payRcdDf.groupby('账户编号', as_index=False)['账户编号'].agg({'次数':'count'})
- maxOverdueNum = np.max(payRcdTimesDf['次数'])
- return maxOverdueNum;
- #近24月贷款最大逾期距离现在的月数 TODO 规则不对
- # 从“信贷交易信息明细”中“非循环贷账户”、“循环额度下分账户”、“循环贷账户”提取,剔除状态为结清、
- # 转出、呆账,MAX(各账户24月内发生逾期的次数),逾期符号判断;数字1234567,字母"G"、"D"、"B"。
- # 统计存在最大逾期期数账户开立日期距报告日期月数,若存在多笔账户,选择开立日期距报告日期最近的。
- def getPayRcdMaxOverdueNumMonth(payRcdDf,df,reportTime,month):
- # payRcdDf = payRcdDf.sort_values(by=["账户编号","还款日期"] , ascending=(True,False))
- # payRcdDf = payRcdDf.groupby(['账户编号']).head(month)
- # if not payRcdDf.empty:
- # maxOverdueNum = np.argmax(payRcdDf['还款状态'])
- # # if maxOverdueNum !=0:
- # payDate = payRcdDf.loc[maxOverdueNum,:]['还款日期']
- # return utils.difMonth(payDate)
- # else:
- # return None;
- # if not df.empty:
- # payRcdDf = payRcdDf.sort_values(by=["账户编号","还款日期"] , ascending=(True,False))
- # payRcdDf = payRcdDf.groupby(['账户编号']).head(month)#先取出近两年
- # payRcdDf = payRcdDf.sort_values(by=["账户编号", "还款状态"], ascending=(True, False))
- # payRcdDf = payRcdDf.groupby(['账户编号']).head(1)#取各个账号的最大值
- # endDateDf = df[["账户编号", "截至日期月份"]];
- # endDateDf = endDateDf.set_index('账户编号')
- # payRcdDf = payRcdDf.join(endDateDf,on='账户编号')
- # maxOverdueNum = None;
- # if not payRcdDf.empty:
- # if np.max(payRcdDf['还款状态']) != 0: # 没有逾期不要与报告器计算
- # maxOverdueNum = int(np.max(payRcdDf['还款状态'] + payRcdDf['截至日期月份']))
- # return maxOverdueNum;
- # else:
- # return None;
- if not df.empty:
- payRcdDf = payRcdDf.sort_values(by=["账户编号", "还款日期"], ascending=(True, False))
- payRcdDf = payRcdDf.groupby(['账户编号']).head(month)
- payRcdDf = payRcdDf[payRcdDf['还款状态'] > 0]
- # maxOverdueNum = np.max(payRcdDf['还款状态'])
- payRcdTimesDf = payRcdDf.groupby('账户编号', as_index=False)['账户编号'].agg({'次数': 'count'})
- if not payRcdTimesDf.empty:
- maxOverdueNumIndex = np.argmax(payRcdTimesDf['次数'])
- row = payRcdTimesDf.loc[maxOverdueNumIndex, :]
- accountNum = row[0]
- openDate = df[df['账户编号'] == (accountNum)].reset_index(drop=True).loc[0, '开立日期']
- return utils.difMonthReportTime(openDate, reportTime);
- return None;
- # 贷款账户近3月逾期期数大于或等于“1”的次数
- def getLoanOverdueTimes(payRcdDf, reportTime,times, month):
- payRcdDfTmp = payRcdDf.sort_values(by=["账户编号", "还款日期"], ascending=(True, False))
- payDate = utils.getLastMonthDate(reportTime,month)
- #汇算帐20210817
- #改为不包含起始区间的1号,如果报告期为6月,取4,5,6,如果报告期为5月取3,4,5,5月2号 -90天 02-01 不能包含
- payRcdDfTmp = payRcdDfTmp[(payRcdDfTmp['还款日期'] > payDate)&(payRcdDfTmp['还款日期'] <= reportTime)]#1208改为区间,两种逻辑都符合
- payRcdDfTmp = utils.replacePayRcdStatusOverdue(payRcdDfTmp)
- overdueTimes = payRcdDfTmp[payRcdDfTmp['还款状态']>=times].index.size
- return overdueTimes;
- # 贷款账户近3月逾期期数大于或等于“1”的金额-汇算帐新增
- def getLoanOverdueAmt(payRcdDf, reportTime,times, month):
- payRcdDfTmp = payRcdDf.sort_values(by=["账户编号", "还款日期"], ascending=(True, False))
- payDate = utils.getLastMonthDate(reportTime,month)
- # 汇算帐20210817
- # 改为不包含起始区间的1号,如果报告期为6月,取4,5,6,如果报告期为5月取3,4,5,5月2号 -90天 02-01 不能包含
- payRcdDfTmp = payRcdDfTmp[(payRcdDfTmp['还款日期'] > payDate)&(payRcdDfTmp['还款日期'] <= reportTime)]#1208改为区间,两种逻辑都符合
- payRcdDfTmp = utils.replacePayRcdStatusOverdue(payRcdDfTmp)
- overdueTimes = payRcdDfTmp[payRcdDfTmp['还款状态']>=times]
- return np.sum(overdueTimes["还款状态值"]);
- #贷款账户24个月是否出现G
- def isExistsInd(payRcdDf,reportTime,ind,month):
- # 过滤为G的还款状态
- payDate = utils.getLastMonthDate(reportTime, month)
- payRcdDfTmp = payRcdDf[payRcdDf['还款日期'] > payDate]
- payRcdDfTmp = payRcdDfTmp[payRcdDfTmp['还款状态'].isin([ind])]
- loanGInd = "0"
- if payRcdDfTmp.index.size > 0:
- loanGInd = "1";
- return loanGInd;
- #历史上担保人代偿次数 汇算帐新增0630
- #近24个月担保人代偿次数 D Z
- def getDbPayCount(payRcdDf, reportTime, payInd,month):
- # 过滤为G的还款状态
- payRcdDfTmp = payRcdDf.sort_values(by=["账户编号", "还款日期"], ascending=(True, False))
- payDate = utils.getLastMonthDate(reportTime, month)
- payRcdDfTmp = payRcdDfTmp[(payRcdDfTmp['还款日期'] > payDate) & (payRcdDfTmp['还款日期'] <= reportTime)]
- payRcdDfTmp = payRcdDfTmp[payRcdDfTmp['还款状态'].isin([payInd])]
- return payRcdDfTmp.index.size;
- # 用户所有贷款账户过去24个月存在逾期的账户数目
- def getLoanOverdueCount(payRcdDf, reportTime, month):
- payRcdDfTmp = payRcdDf.sort_values(by=["账户编号", "还款日期"], ascending=(True, False))
- payDate = utils.getLastMonthDate(reportTime,month)
- # payRcdDfTmp = payRcdDfTmp[payRcdDfTmp['还款日期']>=payDate]
- # 汇算帐20210817
- # 改为不包含起始区间的1号,如果报告期为6月,取4,5,6,如果报告期为5月取3,4,5,5月2号 -90天 02-01 不能包含
- payRcdDfTmp = payRcdDfTmp[(payRcdDfTmp['还款日期'] > payDate) & (payRcdDfTmp['还款日期'] <= reportTime)]
- payRcdDfTmp = utils.replacePayRcdStatusOverdue(payRcdDfTmp)
- overdueCountDf = payRcdDfTmp[payRcdDfTmp['还款状态']>0]
- return overdueCountDf['账户编号'].unique().size;
- # 用户所有贷款账户过去24个月存在逾期的账户数目
- def getLoanNormalCount(payRcdDf, reportTime, month):
- payRcdDfTmp = payRcdDf.sort_values(by=["账户编号", "还款日期"], ascending=(True, False))
- payDate = utils.getLastMonthDate(reportTime,month)
- # payRcdDfTmp = payRcdDfTmp[payRcdDfTmp['还款日期']>=payDate]
- payRcdDfTmp = payRcdDfTmp[(payRcdDfTmp['还款日期'] > payDate) & (payRcdDfTmp['还款日期'] <= reportTime)]
- payRcdDfTmp = utils.replacePayRcdStatusOverdue(payRcdDfTmp)
- overdueCountDf = payRcdDfTmp[payRcdDfTmp['还款状态']>0]
- payRcdDfAll = payRcdDf[payRcdDf['还款日期'] > payDate]
- return payRcdDfAll['账户编号'].unique().size-overdueCountDf['账户编号'].unique().size;
- #按报告期计算
- def getPayRcdMaxOverdueNumX(payRcdDf,reportTime,month):
- if payRcdDf.empty:
- return 0
- payRcdDfTmp = payRcdDf.sort_values(by=["账户编号", "还款日期"], ascending=(True, False))
- payDate = utils.getLastMonthDate(reportTime, month)
- # payRcdDfTmp = payRcdDfTmp[payRcdDfTmp['还款日期'] >= payDate]
- payRcdDfTmp = payRcdDfTmp[(payRcdDfTmp['还款日期'] > payDate) & (payRcdDfTmp['还款日期'] <= reportTime)]
- payRcdDfTmp = utils.replacePayRcdStatusOverdue(payRcdDfTmp)
- if payRcdDfTmp.empty:
- return 0
- maxOverdueNum = np.max(payRcdDfTmp['还款状态'])
- return maxOverdueNum;
- #用户过去3个月最大逾期期数
- def getPayRcdMaxOverdueNumAllAccout(loanPayRecordMergeDf,creditCardPayRecordMergeDf,creditCardPayRecordMergeDfZ,reportTime,month):
- loanOverdueMax = getPayRcdMaxOverdueNumX(loanPayRecordMergeDf, reportTime, month)
- creditCardOverdueMax = getPayRcdMaxOverdueNumX(creditCardPayRecordMergeDf, reportTime, month)
- creditCardOverdueMaxZ = getPayRcdMaxOverdueNumX(creditCardPayRecordMergeDfZ, reportTime, month)
- overdueNum = [loanOverdueMax, creditCardOverdueMax, creditCardOverdueMaxZ]
- return np.max(overdueNum)
- #近12个月最大逾期期数--不包括准贷记卡,汇算帐需求
- def getPayRcdMaxOverdueNumAccout(loanPayRecordMergeDf,creditCardPayRecordMergeDf,reportTime,month):
- loanOverdueMax = getPayRcdMaxOverdueNumX(loanPayRecordMergeDf, reportTime, month)
- creditCardOverdueMax = getPayRcdMaxOverdueNumX(creditCardPayRecordMergeDf, reportTime, month)
- overdueNum = [loanOverdueMax, creditCardOverdueMax]
- return np.max(overdueNum)
- #贷款24期还款记录次数
- def getPayRcdCount(payRcdDf,normalDf,month):
- payStatus = ["G", "D", "C", "N", "M", "1", "2", "3", "4", "5", "6", "7"]
- # 贷款24期还款记录次数 剔除结清 转出 呆账
- payRcdTimesDf = payRcdDf[payRcdDf['账户编号'].isin(normalDf['账户编号'].values)]
- payRcdTimesDf = payRcdTimesDf.sort_values(by=["账户编号", "还款日期"], ascending=(True, False))
- payRcdTimesDf = payRcdTimesDf.groupby(['账户编号']).head(month)
- # 从“贷款信息”中提取,剔除“账户状态”为结清、转出、呆账、呆帐后,各账户的还款次数统计“24个月(账户)还款状态”包含"G","D","C","N","M"及数字的个数,MAX(各账户的还款次数)
- payRcdTimesDf = payRcdTimesDf[payRcdTimesDf['还款状态'].isin(payStatus)]
- payRcdTimes = payRcdTimesDf.groupby(['账户编号'])['还款状态'].count()
- return np.max(payRcdTimes)
- #最近6个月有贷款还款记录的月份数
- def getPayRcdCountNew(payRcdDf,reportTime,month):
- # reportTime = str(np.datetime64(reportTime, "M")) + "-02"
- reportTime = utils.get_last_month_first_day_v2(reportTime)
- payDate = utils.getLastMonthDate(reportTime, month)
- # payRcdDfTmp = payRcdDf[payRcdDf['还款日期'] >= payDate]
- payRcdDfTmp = payRcdDf[(payRcdDf['还款日期'] > payDate) & (payRcdDf['还款日期'] <= reportTime)]
- payStatus = ["Z","G", "D", "C", "N", "M", "1", "2", "3", "4", "5", "6", "7"]
- payRcdTimesDf = payRcdDfTmp[payRcdDfTmp['还款状态'].isin(payStatus)]
- count = payRcdTimesDf["还款日期"].unique().size;
- return count
|