给定以下数据集:
group_id | from_date | to_date | |||
---|---|---|---|---|---|
0 | 2020-01-01 | 0 | 2020-02-01 | 2020-03-01 | |
0 | 2020-03-01 | 2020-04-01 | |||
1 | 2020-02-01 | 2020-03-01 |
您的方法几乎是正确的,只需聚合为系列,然后再进行重命名:
# ensure datetime
df['from_date'] = pd.to_datetime(df['from_date'])
df['to_date'] = pd.to_datetime(df['to_date'])
(df.groupby('group_id')
.apply(lambda g: g['to_date'].max()-g['from_date'].min())
.reset_index(name='duration_days')
)
输出:
group_id duration_days
0 0 91 days
1 1 60 days
让我们不要处理应用lambda。melt
+np.ptp
out = df.melt('group_id').groupby('group_id')['value'].agg(np.ptp).reset_index(name = 'duration_days')
Out[16]:
group_id duration_days
0 0 91 days
1 1 60 days
计算每个组的最大值和最小值(我正在确保它们是日期时间对象,它们可能已经是了(:
maxi = df.groupby('group_id').to_date.max()
mini = df.groupby('group_id').from_date.min()
然后将它们彼此相减:
(maxi - mini).reset_index()
输出:
group_id to_date
0 0 91 days
1 1 60 days
另一种可能的解决方案,基于pivot_table
:
# previous conversion to datetime
cols = ['from_date', 'to_date']
df[cols] = df[cols].apply(pd.to_datetime)
(df.pivot_table(values=cols, index='group_id', aggfunc={
cols[0]: 'min', cols[1]: 'max'})
.assign(duration = lambda x: x.pop('to_date').sub(x.pop('from_date')))
.reset_index())
输出:
group_id duration
0 0 91 days
1 1 60 days