2017-08-02 83 views
0

我有一个有三列的pandas数据帧。开始和结束日期以及月份。熊猫在特定月份的两个日期之间得到天数

我想添加一个月份内有多少天是在两个日期之间的列。我开始做applycalendar图书馆和一些数学,但它开始变得非常复杂。我敢打赌pandas有一个简单的解决方案,但我正在努力找到它。

输入:

import pandas as pd 
df1 = pd.DataFrame(data=[['2017-01-01', '2017-06-01', '2016-01-01'], 
         ['2015-03-02', '2016-02-10', '2016-02-01'], 
         ['2011-01-02', '2018-02-10', '2016-03-01']], 
        columns=['start date', 'end date date', 'Month']) 

所需的输出:

start date end date date  Month Days in Month 
0 2017-01-01 2017-06-01 2016-01-01    0 
1 2015-03-02 2016-02-10 2016-02-01    10 
2 2011-01-02 2018-02-10 2016-03-01    31 

回答

3

有一个解决方案: 获得通过pd.date_rangestartend日期之间的日期列表,然后检查有多少日有相同yearmonth与目标月份。

def overlap(x): 
    md = pd.to_datetime(x[2]) 
    cand = [(ad.year, ad.month) for ad in pd.date_range(x[0], x[1])] 
    return len([x for x in cand if x ==(md.year, md.month)]) 
df1["Days in Month"]= df1.apply(overlap, axis=1) 

您将获得:

start date end date date  Month Days in Month 
0 2017-01-01 2017-06-01 2016-01-01    0 
1 2015-03-02 2016-02-10 2016-02-01    10 
2 2011-01-02 2018-02-10 2016-03-01    31 
+0

很简单。谢谢。 – user2242044

1

您可以通过

df = df.applymap(lambda x: pd.to_datetime(x))

你的细胞转化为datetime然后找到交集天功能

def intersectionDaysInMonth(start, end, month): 
    end_month = month.replace(month=month.month + 1) 
    if month <= start <= end_month: 
     return end_month - start 
    if month <= end <= end_month: 
     return end - month 
    if start <= month < end_month <= end: 
     return end_month - month 

    return pd.to_timedelta(0) 

Then apply

df['Days in Month'] = df.apply(lambda row: intersectionDaysInMonth(*row).days, axis=1) 
相关问题