计算有多个开始结束日期的总历时月份或者年份

比如说用户有多笔贷款,每个贷款都有开始和结束时间,那么我们需要计算用户需要还款的总的月份(年份)(或者说贷款持续时间),如:

 我们需要计算用户需要还款的月份数,以便于后面计算平均月供,由于有些日期是重合的,我们就不能计算多次。还有一些是跳跃的,也不能多计算,不能直接使用最大最小时间去计算差值

有两种方法:

第一种:可以根据开始和结束时间生成对应的时间序列(比如开始和结束时间分别是2020-01-01,2020-04-01,我们就生成[2020-01,2020-02,2020-03,2020-04),但是这种方法再数据量特别大的时候,就不好使了,会占用很多的内

第二种:可以将所有的日期拿出来,然后排序,然后使用set,然后再使用np.diff 

下面我附上这两种方法的代码

第一种

#首先根据开始结束时间生成时间序列,左开右闭还是右开左闭,可以自己设置参数
t['data_list'] =t.apply(lambda x:[i.date().strftime('%Y-%m') for i in (pd.date_range(start = x.opendate, 
                                                      end= x.end_pay_month, 
                                                      freq = 'M')).tolist()],axis=1)

#再使用groupby,先合并每一个时间序列,然后使用set去重,然后在使用len计算长度
t.groupby('reportno').apply(lambda x:len(set(np.concatenate(x.data_list.values))))

#该方法会比下面的准确一点,因为下面的除以30,不够准确

第二种

tmp_month = data_amount.groupby('某某ID号').apply(lambda x:list(x.opendate)+list(x.end_date))  #可以是结束时间或者是当前时间(看你自己需要)

from dateutil import parser
import math
def due_month(x):
    if set(x)=={0}:
        x=0
    else:
        x=set(map(lambda x :x.strftime('%Y-%m'),x))  #先转为月份形式,好后面使用set去重
        x = sorted(x)  #要排序,
        l=[]
        for i in range(len(x)):
            l.append(str(x[i])+'-01')
        l=[parser.parse(i) for i in l]  #需要再转回datetime.date格式才可以使用np.diff
        l=np.diff(l)
        l=sum([math.floor(i.days/30) for i in l])  #除以30,转化为月份数
        x= l
    return x 

tmp_month=pd.DataFrame(tmp_month.apply(due_month))
原文地址:https://www.cnblogs.com/cgmcoding/p/14187534.html