【问题标题】:Pandas Dataframe calculate Time difference for each group and Time difference between two different groupsPandas Dataframe 计算每个组的时间差和两个不同组之间的时间差
【发布时间】:2020-11-24 09:57:49
【问题描述】:

我已经创建了一个这样的数据框:

import pandas as pd
d = {'Time': ['01.07.2019, 06:21:33', '01.07.2019, 06:32:01', '01.07.2019, 06:57:33', '01.07.2019, 07:24:33','01.07.2019, 08:26:25', '01.07.2019, 09:12:44']
     ,'Action': ['Opened', 'Closed', 'Opened', 'Closed', 'Opened', 'Closed']
     ,'Name': ['Bayer', 'Bayer', 'ITM', 'ITM', 'Geco' , 'Geco'],
               'Group': ['1', '1', '2','2','3','3']}
df = pd.DataFrame(data=d)

output:

    Time                    Action  Name    Group
0   01.07.2019, 06:21:33    Opened  Bayer   1
1   01.07.2019, 06:32:01    Closed  Bayer   1
2   01.07.2019, 06:57:33    Opened  ITM     2
3   01.07.2019, 07:24:33    Closed  ITM     2
4   01.07.2019, 08:26:25    Opened  Geco    3
5   01.07.2019, 09:12:44    Closed  Geco    3

所以现在我正在尝试计算每个组的时差以及这些组之间的时差(以分钟为单位)。例如,拜耳集团的时间差应该是 10 分 28 秒,拜耳和 ITM 之间的时间差应该是 25 分 32 秒。之后,同一组之间的时差应显示在组开始的同一行的列中,两个不同组之间的时差应显示在组结束的同一行的另一列中。

所以希望的输出是:

    Time                    Action  Name    Group Time Difference(names) Time Difference(groups)
0   01.07.2019, 06:21:33    Opened  Bayer   1          10:28
1   01.07.2019, 06:32:01    Closed  Bayer   1                                   25:32
2   01.07.2019, 06:57:33    Opened  ITM     2          27:00         
3   01.07.2019, 07:24:33    Closed  ITM     2                                   1:01:52
4   01.07.2019, 08:26:25    Opened  Geco    3          46:19
5   01.07.2019, 09:12:44    Closed  Geco    3

我该怎么做?

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    首先从字符串生成日期时间,然后是一些分组和差异:

    df["Time"] = pd.to_datetime(df["Time"])
    df["d1"] = df.groupby("Name")["Time"].diff().shift(-1).fillna("")
    df["d2"] = (
        df.groupby((df["Action"] == "Closed").cumsum())["Time"]
        .diff()
        .shift(-1)
        .fillna("")
    )
    
    

    生产

    |    | Time                | Action   | Name   |   Group | d1              | d2              |
    |---:|:--------------------|:---------|:-------|--------:|:----------------|:----------------|
    |  0 | 2019-01-07 06:21:33 | Opened   | Bayer  |       1 | 0 days 00:10:28 |                 |
    |  1 | 2019-01-07 06:32:01 | Closed   | Bayer  |       1 |                 | 0 days 00:25:32 |
    |  2 | 2019-01-07 06:57:33 | Opened   | ITM    |       2 | 0 days 00:46:19 |                 |
    |  3 | 2019-01-07 07:24:33 | Closed   | ITM    |       2 |                 | 0 days 01:01:52 |
    |  4 | 2019-01-07 08:26:25 | Opened   | Geco   |       3 | 0 days 00:27:00 |                 |
    |  5 | 2019-01-07 09:12:44 | Closed   | Geco   |       3 |                 |                 |
    

    解释一下d2 计算,对于每个新的'Closed' 行,此(df['Action'] == 'Closed').cumsum() 递增1。在这里,为了清楚起见,我将它与Action 一起打印,使用这个

    df['d2_cond'] = (df['Action'] == 'Closed').cumsum()
    df[['Action', 'd2_cond']]
    

    打印

    
    Action  d2_cond
    0   Opened  0
    1   Closed  1
    2   Opened  1
    3   Closed  2
    4   Opened  2
    5   Closed  3
    

    所以我们可以在这个列表中groupby 将每个Closed 与对应的下一个Opened 放在一起

    【讨论】:

    • 很好的答案。你能详细说明d2的创建吗,稍微解释一下会很有帮助。
    • @piterbarg 这样工作正常!!伟大的!另一个问题:如果下一行的时间例如是第二天,是否可以从头开始计算?所以不是 1 天 20 分钟
    • @Arthi 很高兴它有帮助。不过,我不确定我是否理解您的后续问题。从什么开始?
    • @piterbarg 例如:如果我们在数据框中有相同的名称但日期不同:( 01.07.2019 14:55:57, Opened, ITM, 1), (02.07.2019 06:55:12,关闭,ITM)它将计算一整天,所以如果第二天进入下一行,它应该在 14:55:57 停止并在第二天从 0 开始计算,我该怎么做?
    • 您可以通过 df['d3'] = df['Time'].apply(lambda d: d - d.floor('d')) 之类的方式计算出每个时间戳从当天午夜开始的偏移量。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-02-02
    • 1970-01-01
    • 1970-01-01
    • 2014-05-20
    • 1970-01-01
    • 2013-08-08
    相关资源
    最近更新 更多