我有一个很大的数据框,如下图所示。数据按ID排序,然后按OnTime
id OnTime OffTime
0 1 2017-08-01 09:38:17 2017-08-01 09:49:31
1 1 2017-08-01 09:53:15 2017-08-01 09:54:50
2 1 2017-08-01 09:57:29 2017-08-01 10:10:42
3 2 2017-08-01 09:02:00 2017-08-01 09:27:15
4 2 2017-08-01 09:29:15 2017-08-01 09:43:41
如果ID相同,我需要计算当前的OnTime和以前的OffTime之间的时间差。 (这种差异称为timeSince)
寻找一种在Python中实现此目标的有效方法。数据框大约有40万行。我已经考虑过按ID分组,但我不确定我如何迭代和计算时差。
输出应如下所示:
timeSince
-1 #since this is the 1st row of ID 1 no previous OffTime exists
3.7333333333333334
2.65
-1 #since this is the 1st row of ID 2 no previous OffTime exists
2.0
答案 0 :(得分:3)
您可以尝试依次使用OffTime
的{{3}}和apply
1
。由于输出为shift
,因此我们需要使用TimeDelta
进行转换,然后取总seconds
,然后除以60
(1minute = 60seconds)
。最后,使用apply
用NaN
然后fillna
填充-1
值。结果:
import pandas as pd
df['OnTime'] = pd.to_datetime(df['OnTime'])
df['OffTime'] = pd.to_datetime(df['OffTime'])
df['timeSince']=df.groupby('id').apply(lambda x: x['OnTime']-x['OffTime'].shift(1)).\
apply(lambda x: x.seconds/60).fillna(-1).\
reset_index(drop=True)
df
id OnTime OffTime timeSince
0 1 2017-08-01 09:38:17 2017-08-01 09:49:31 -1.000000
1 1 2017-08-01 09:53:15 2017-08-01 09:54:50 3.733333
2 1 2017-08-01 09:57:29 2017-08-01 10:10:42 2.650000
3 2 2017-08-01 09:02:00 2017-08-01 09:27:15 -1.000000
4 2 2017-08-01 09:29:15 2017-08-01 09:43:41 2.000000
答案 1 :(得分:3)
使用GroupBy
+ lambda
很诱人,但这不是必需的:
df['timeSince'] = (df['OnTime'] - df.groupby('id')['OffTime'].shift())
df['timeSince'] = (df['timeSince'] / np.timedelta64(1, 'm')).fillna(-1)
print(df)
OffTime OnTime id timeSince
0 2017-08-01 09:49:31 2017-08-01 09:38:17 1 -1.000000
1 2017-08-01 09:54:50 2017-08-01 09:53:15 1 3.733333
2 2017-08-01 10:10:42 2017-08-01 09:57:29 1 2.650000
3 2017-08-01 09:27:15 2017-08-01 09:02:00 2 -1.000000
4 2017-08-01 09:43:41 2017-08-01 09:29:15 2 2.000000