我想在groupby上执行自定义功能,例如,如果我的数据具有以下格式。
personid jobid start_date end_date
1 1 2015-01-01 2016-01-30
1 2 2016-01-01 2017-01-01
我想计算同一个人的两个不同工作的两个日期之间的重叠。使用
是明智的吗?df.groupby(personid).agg(x)
但是,我将如何在函数x中引用不同记录的开始日期和结束日期。
代码的输出类似于
personid overlap
1 30
答案 0 :(得分:2)
我认为您需要使用groupby
自定义函数,其中选择start
和end
日期时间的第一个和最后一个值,获取date_range
,然后找到length
numpy.intersect1d
的交叉点:
def f(x):
a = pd.date_range(x['start_date'].iat[0], x['end_date'].iat[0], unit='d')
b = pd.date_range(x['start_date'].iat[-1], x['end_date'].iat[-1], unit='d')
return pd.Series(len(np.intersect1d(a,b)), index=['overlap'])
df = df.groupby('personid').apply(f).reset_index()
print (df)
personid overlap
0 1 366
1 2 6
样品:
df = pd.DataFrame({'start_date': [pd.Timestamp('2015-01-01 00:00:00'), pd.Timestamp('2015-01-01 00:00:00'), pd.Timestamp('2015-01-01 00:00:00'), pd.Timestamp('2015-01-05 00:00:00')], 'personid': [1, 1, 2, 2], 'end_date': [pd.Timestamp('2016-01-30 00:00:00'), pd.Timestamp('2016-01-01 00:00:00'), pd.Timestamp('2015-01-25 00:00:00'), pd.Timestamp('2015-01-10 00:00:00')], 'jobid': [1, 2, 1, 2]})
print (df)
end_date jobid personid start_date
0 2016-01-30 1 1 2015-01-01
1 2016-01-01 2 1 2015-01-01
2 2015-01-25 1 2 2015-01-01
3 2015-01-10 2 2 2015-01-05