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