如何计算数据框中日期时间列的两个或多个类别的时间

How to calculate the time for two or more category for datetime column in dataframe

我有一个由日期时间、class 列组成的数据框。 class 列的值为 'open'、'close'。这是一个物联网数据。我必须计算总开放时间和总关闭时间。数据框是-

index   datetime                    class
------------------------------------------
0      2020-10-05 08:55:00.161326   open
1      2020-10-05 09:00:00.137587   close
2      2020-10-05 09:05:00.089382   close
3      2020-10-05 09:10:00.219278   close
4      2020-10-05 09:15:00.160964   close
5      2020-10-06 09:20:00.315548   close
6      2020-10-06 09:25:00.080932   open
7      2020-10-06 09:30:00.335536   open
8      2020-10-06 09:35:00.202047   close
9      2020-10-06 09:45:00.242022   open

我需要得到的回应是-

index   day_count   hour_count          class
-----------------------------------------------
0              0    0:15:00.097376      open
1              1    23:59:59.918860     close

基本上我正在尝试使用数据捕获传感器的运行时间。如果可能的话,我也在寻找 postgresql 中的解决方案。我更喜欢 postgresql 而不是 dataframe。

Postgres 解决方案可能如下所示:

step-by-step demo:db<>fiddle

SELECT
    class,
    SUM(duration)                                                         -- 5
FROM (
    SELECT
        *,
        lead(datetime) OVER (ORDER BY datetime) - datetime as duration    -- 4
    FROM (
        SELECT
            *,
            COALESCE(                                                     -- 2
                (class != lag(class) OVER (ORDER BY datetime))::int,      -- 1
                 1
            ) as state
        FROM 
            t
    ) s
    WHERE state != 0                                                      -- 3
) s
GROUP BY class
  1. lag() 将当前 class 值移动到下一行。可以比较这两个值。如果它们相等,则结果为 0,否则为 1
  2. COALESCE 只是第一个记录,当然,它不包含以前的值
  3. 删除所有具有 value = 0 的值(中间步骤)
  4. 之后,lead() 值将下一个日期时间值复制到当前行。因此,可以计算下一个和当前 datetime 值之间的差异。现在,我们知道了从一个 class 值更改为另一个值的区别。
  5. 最终:按 class 分组并对持续时间求和。

您可以只使用 window 函数和聚合:

select class, sum(lead_datetime - datetime) as duration
from (
    select t.*, lead(datetime) over(order by datetime) lead_datetime
    from mytable t
) t
group by class

对于每一行,这将计算直到下一行的增量持续时间,然后将其关联到当前行的 class。无需跳过中间步骤,只需将持续时间相加即可。