我有一个包含三列的pandas
数据框。开始和结束日期和月份。
我想添加一个列,列出两个日期之间的月份。我开始使用apply
,calendar
库和一些数学,但它开始变得非常复杂。我打赌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
答案 0 :(得分:3)
有一个解决方案:
在pd.date_range
和start
日期之间按end
获取日期列表,然后检查与目标月份相同的year
和month
的日期。< / p>
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
答案 1 :(得分:1)
您可以通过
将您的手机信号转换为日期时间 df = df.applymap(lambda x: pd.to_datetime(x))
然后找到具有功能的交叉日
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)
然后申请
df['Days in Month'] = df.apply(lambda row: intersectionDaysInMonth(*row).days, axis=1)