首页 > 解决方案 > 从 pandas python 中的数据帧创建持续时间

问题描述

我有下面的数据框,现在我想计算每个SOURCE处于Bad状态的时间。

在此处输入图像描述

例如,SOURCE A2020-12-16 14:57:562020-12-16-14:58:01处于bad status 大约 5 秒,同样 SOURCE A 在不同时间也处于 bad status邮票。我想计算每个来源处于不良状态时的持续时间

在此处输入图像描述

下面是数据框代码:

import pandas as pd
import datetime

times=[datetime.datetime(2020, 12, 16, 14, 57, 56, 647689),datetime.datetime(2020, 12, 16, 14, 57, 59, 650766),datetime.datetime(2020, 12, 16, 14, 58, 1, 655858),datetime.datetime(2020, 12, 16, 14, 58, 4, 657299),datetime.datetime(2020, 12, 16, 14, 58, 5, 661615),datetime.datetime(2020, 12, 16, 14, 58, 6, 662729),datetime.datetime(2020, 12, 16, 14, 58, 10, 663151),datetime.datetime(2020, 12, 16, 14, 58, 13, 664116),datetime.datetime(2020, 12, 16, 14, 58, 16, 664501),datetime.datetime(2020, 12, 16, 14, 58, 17, 668526)]
source=['A','A','A','A','A','A','A','B','B','B']
status=['Bad','Bad','Good','Bad','Bad','Good','Good','Good','Good','Good']
df=pd.DataFrame({'time':times, 'source':source,'status':status})

标签: pythonpandasdataframedatetime

解决方案


In [299]: df
Out[299]:
                        time source status  grp
0 2020-12-16 14:57:56.647689      A    Bad    1
1 2020-12-16 14:57:59.650766      A    Bad    1
2 2020-12-16 14:58:01.655858      A   Good    2
3 2020-12-16 14:58:04.657299      A    Bad    3
4 2020-12-16 14:58:05.661615      A    Bad    3
5 2020-12-16 14:58:06.662729      A   Good    4
6 2020-12-16 14:58:10.663151      A   Good    4
7 2020-12-16 14:58:13.664116      B   Good    1
8 2020-12-16 14:58:16.664501      B   Good    1
9 2020-12-16 14:58:17.668526      B   Good    1

In [340]: df['time2'] = df.groupby('source').time.shift(-1)

In [341]: df['grp'] = df.groupby('source').status.transform(lambda x: (x != x.shift()).cumsum())


In [343]: df[df.status == 'Bad'].groupby(['source', 'grp']).agg({'time': min, 'time2': max}).reset_index().drop('grp', axis=1)
Out[343]:
  source                       time                      time2
0      A 2020-12-16 14:57:56.647689 2020-12-16 14:58:01.655858
1      A 2020-12-16 14:58:04.657299 2020-12-16 14:58:06.662729

逻辑

  1. 创建一个上移时间列以具有下一个时间戳(需要 groupby 源,因为我假设您不希望混合源)
  2. grp列为源中的每个状态分配一个组号,以便连续状态获得相同的值
  3. 这很简单 - 只需要过滤“坏”组,然后按源和 grp 列分组并执行所需的 aggs

推荐阅读