查找两列之间的最早和最新日期

时间:2019-01-15 14:56:13

标签: pandas group-by python-3.5

我有以下数据框df

    id  start   finish  location
0   1   2015-12-14 16:44:00 2015-12-15 18:00:00 A
1   1   2015-12-15 18:00:00 2015-12-16 13:00:00 B
2   1   2015-12-16 13:00:00 2015-12-16 20:00:00 C
3   2   2015-12-10 13:15:00 2015-12-12 13:45:00 B
4   2   2015-12-12 13:45:00 2015-12-12 19:45:00 A
5   3   2015-12-15 07:45:00 2015-12-15 18:45:00 A
6   3   2015-12-15 18:45:00 2015-12-18 07:15:00 D
7   3   2015-12-18 07:15:00 2015-12-19 10:45:00 C
8   3   2015-12-19 10:45:00 2015-12-20 09:00:00 H

我想为每个ID找到id_start_dateid_end_date

在上面的示例中,每行都有开始和结束日期。我想要两个新列id_start_dateid_end_date。在id_start_date列中,我想在特定于每个ID的开始列中找到最早的日期。这很容易。我可以先根据ID和开始对数据进行排序,然后可以仅选择每个ID中的第一个开始日期,也可以根据ID进行分组,然后使用聚合函数在开始列中查找最小日期。对于id_end_date,我可以这样做。我可以根据ID进行分组,并使用聚合函数在完成列中找到最长日期。

df1 = df.sort_values(['id','start'],ascending=True)
gp = df1.groupby('id')
gp_out = gp.agg({'start': {'mindate': np.min}, 'finish': {'maxdate': np.max}})

当我打印gp_out时,它确实显示了正确的日期,但是如何将它们写回到原始数据帧df中。我期望以下内容:

id  start   finish  location id_start_date id_end_date
0   1   2015-12-14 16:44:00 2015-12-15 18:00:00 A 2015-12-14 16:44:00 2015-12-16 20:00:00
1   1   2015-12-15 18:00:00 2015-12-16 13:00:00 B 2015-12-14 16:44:00 2015-12-16 20:00:00
2   1   2015-12-16 13:00:00 2015-12-16 20:00:00 C 2015-12-14 16:44:00 2015-12-16 20:00:00
3   2   2015-12-10 13:15:00 2015-12-12 13:45:00 B 2015-12-10 13:15:00 2015-12-12 19:45:00
4   2   2015-12-12 13:45:00 2015-12-12 19:45:00 A 2015-12-10 13:15:00 2015-12-12 19:45:00
5   3   2015-12-15 07:45:00 2015-12-15 18:45:00 A 2015-12-15 07:45:00 2015-12-20 09:00:00
6   3   2015-12-15 18:45:00 2015-12-18 07:15:00 D 2015-12-15 07:45:00 2015-12-20 09:00:00
7   3   2015-12-18 07:15:00 2015-12-19 10:45:00 C 2015-12-15 07:45:00 2015-12-20 09:00:00
8   3   2015-12-19 10:45:00 2015-12-20 09:00:00 H 2015-12-15 07:45:00 2015-12-20 09:00:00

如何将最后两列放入原始数据帧df中?

1 个答案:

答案 0 :(得分:1)

使用transform

g=df.groupby('id')
df['id_start_date']=g['start'].transform('min')
df['id_end_date']=g['finish'].transform('max')