我想计算一个列为True的持续时间,该列的索引包含数据帧中的秒数。
我有一个数据帧:
df = pd.DataFrame({'a': {0.0: False, 0.5: False, 1.0:False, 1.5:True, 2.0:True, 4.0:False, 8.0:True,10.0:False}})
>>> df
a
0.0 False
0.5 False
1.0 False
1.5 True
2.0 True
4.0 False
8.0 True
10.0 False
数据帧的索引包含秒。我认为最合适的方法是提取True值的每个部分的第一次出现,直到找到一个false并有一个连续的总数。RT是运行总数结果会是这样的:
>>> df
a
0.0 False
0.5 False
1.0 False
1.5 True < - found first occurance (1.5)
2.0 True
4.0 False < - found false (4.0) (running total: 4-1.5 + RT = 2.5)
8.0 True < - found first occurance (8.0)
10.0 False < - found false (10.0) (running total: 10-8 + RT = 4.5)
RT = 4.5 seconds
创建一个唯一标记False
值的辅助列——这些数字表示True
条纹的可能结束。然后将False行与属于前一条的第一个True行合并,并计算时间差的总和。
df = df.rename_axis(index='time').reset_index()
df['end'] = (~df['a']).cumsum()
# time a end
#0 0.0 False 1
#1 0.5 False 2
#2 1.0 False 3
#3 1.5 True 3
#4 2.0 True 3
#5 4.0 False 4
#6 8.0 True 4
#7 10.0 False 5
res = pd.merge(df[df['a'].eq(False)],
df[df['a'].eq(True)].assign(end=df['end']+1).drop_duplicates('end'),
on='end')
# time_x a_x end time_y a_y
#0 4.0 False 4 1.5 True
#1 10.0 False 5 8.0 True
(res['time_x'] - res['time_y']).sum()
#4.5
为了解释合并,左边的DataFrame只是原始数据中包含False的每一行:
df[df['a'].eq(False)]
# time a end
#0 0.0 False 1
#1 0.5 False 2
#2 1.0 False 3
#5 4.0 False 4
#7 10.0 False 5
正确的DataFrame稍微复杂一些。我只取True行,但在end
上取drop_duplicates,因为我们只想在存在连续True值时保持第一个True。最后,因为我们想将True与其后的False匹配,所以我们需要向end
添加一个。
df[df['a'].eq(True)].assign(end=df['end']+1).drop_duplicates('end')
# time a end
#3 1.5 True 4
#6 8.0 True 5
现在,通过合并on='end'
,我们可以将第一个True(在一组可能连续的True值中(与其后的第一个False值进行匹配。由于我们将索引作为'time'
,我们可以计算这些观测值之间的时间差。