Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 熊猫数据帧计算每组的时差以及两个不同组之间的时差_Python_Pandas_Dataframe - Fatal编程技术网

Python 熊猫数据帧计算每组的时差以及两个不同组之间的时差

Python 熊猫数据帧计算每组的时差以及两个不同组之间的时差,python,pandas,dataframe,Python,Pandas,Dataframe,我创建了这样一个数据帧: 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', 'Op

我创建了这样一个数据帧:

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

我怎样才能做到这一点呢?

首先从字符串生成datetime,然后是一些groupbys和Diff:

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计算,这个df['Action']=='Closed'。对于每一个新的'Closed'行,cumsum递增1。在这里,为了清晰起见,我使用此

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将每个已关闭项与相应的下一个已打开项组合在一起,首先从字符串中生成datetime,然后是一些groupbys和Diff:

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计算,这个df['Action']=='Closed'。对于每一个新的'Closed'行,cumsum递增1。在这里,为了清晰起见,我使用此

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

因此,我们可以在此列表上分组,将每个已关闭项与相应的下一个已打开项组合在一起

非常好的答案。你能详细解释一下d2的创建吗?一点解释会有帮助的。@Piterberg,这样做很好!!伟大的另一个问题:如果下一行中的时间是例如第二天,是否可以从头开始计算?所以不是说有1天20分钟minutes@Arthi很高兴这有帮助。我不确定我是否理解你的后续问题。从什么开始?@Piterberg举个例子:如果我们在数据框中有相同的名称,但日期不同:2019年7月1日14:55:57,开放,ITM,2019年7月1日06:55:12,关闭,它会计算一整天,所以如果第二天在下一行,它应该在14:55:57停下来,从第二天的0开始计算,我怎么做呢?你可以通过类似df['d3']=df['Time'].applylambda d:d-d.floor'd.的方式计算出从那天午夜开始的每个时间戳的偏移量。回答很好。你能详细解释一下d2的创建吗?一点解释会有帮助的。@Piterberg,这样做很好!!伟大的另一个问题:如果下一行中的时间是例如第二天,是否可以从头开始计算?所以不是说有1天20分钟minutes@Arthi很高兴这有帮助。我不确定我是否理解你的后续问题。从什么开始?@Piterberg举个例子:如果我们在数据框中有相同的名称,但日期不同:2019年7月1日14:55:57,开放,ITM,2019年7月1日06:55:12,关闭,它会计算一整天,所以如果第二天在下一行中,它应该在14:55:57停止,然后从第二天的0开始计算,我怎么做呢?你可以通过类似df['d3']=df['Time'].applylambda d:d-d.floor'd'的方式计算出从那天午夜开始的每个时间戳的偏移量。