按runid分组计算datetime列相对起始行的时长
按分组计算与组内首行的时间差(无辅助列实现)
问题描述
有如下结构的pandas DataFrame:
dttm runid 9/7/2023 00:10 1694020173 9/7/2023 00:10 1694020173 9/7/2023 00:10 1694020173 9/7/2023 00:10 1694020173 9/7/2023 00:10 1694020173 9/29/2023 20:31 1695908276 9/29/2023 20:31 1695908276 9/29/2023 20:31 1695908276 9/29/2023 20:31 1695908276 9/29/2023 20:31 1695908276
其中dttm列的数据类型为datetime64[ns]。需要新增一列Duration,展示按runid分组后,每行dttm与该组首行时间的差值(以秒为单位)。
目前已通过添加辅助列的方式实现:
df['_Start_Time']=df.groupby('runid')['dttm'].transform('min') df['Duration']=((df['dttm']-df['_Start_Time']).dt.total_seconds())
想知道有没有更优雅的实现方式,不需要额外的辅助列,比如用apply方法?
解决方案
当然可以不用辅助列,直接一步完成计算,这里提供几种简洁的实现方式:
1. 链式调用transform(最简洁)
直接把分组取最小时间的逻辑内联到计算中,一步生成目标列:
df['Duration'] = (df['dttm'] - df.groupby('runid')['dttm'].transform('min')).dt.total_seconds()
如果每组的首行就是该组最早的时间,也可以用transform('first')替代transform('min'),效果完全一致:
df['Duration'] = (df['dttm'] - df.groupby('runid')['dttm'].transform('first')).dt.total_seconds()
2. 使用groupby+apply实现
如果偏好apply方法,可以针对每个分组单独计算每行与组内首行的时间差:
df['Duration'] = df.groupby('runid')['dttm'].apply( lambda x: (x - x.iloc[0]).dt.total_seconds() ).reset_index(level=0, drop=True)
这里x.iloc[0]获取每组的首行时间,计算完成后通过reset_index去掉分组索引,让结果和原DataFrame的行对齐。
内容的提问来源于stack exchange,提问作者thentangler
相关产品推荐
相关产品推荐

