【问题标题】:What is the way to group only those identical groups that are adjacent to each other in python?在python中只对那些彼此相邻的相同组进行分组的方法是什么?
【发布时间】:2020-12-03 07:00:39
【问题描述】:

输入:

   Column1    Event   Time
0   type1     A       2020-11-01 05:26:12
1   type1     A       2020-11-01 05:26:17
2   type1     A       2020-11-01 05:26:22
3   type1     B       2020-11-01 05:26:32
4   type1     B       2020-11-01 05:26:37
5   type1     A       2020-11-01 05:26:42
6   type1     A       2020-11-01 05:26:47
7   type1     C       2020-11-01 05:26:52
8   type1     C       2020-11-01 05:27:02
9   type1     B       2020-11-01 05:27:07
10  type1     B       2020-11-01 05:27:15

期望的输出:

    Column1   Event   Min(Time)             Max(Time)            EventEndTime

0   type1     A       2020-11-01 05:26:12   2020-11-01 05:26:22  2020-11-01 05:26:32
1   type1     B       2020-11-01 05:26:32   2020-11-01 05:26:37  2020-11-01 05:26:42
2   type1     A       2020-11-01 05:26:42   2020-11-01 05:26:47  2020-11-01 05:26:52
3   type1     C       2020-11-01 05:26:52   2020-11-01 05:27:02  2020-11-01 05:27:07
4   type1     B       2020-11-01 05:27:07   2020-11-01 05:27:15

我已尝试但无法仅对相邻的相同事件进行分组,我最终通过以下代码行获得了总体最小值和最大值:

 data.groupby(['Column1','Event']).agg({'Time': ['min','max']}) 

【问题讨论】:

    标签: python python-3.x pandas pandas-groupby data-analysis


    【解决方案1】:

    您可以使用辅助系列将移位值与累积总和与g 进行比较,并且聚合用于字典中的命名聚合,因此用于解包**,最后由DataFrame.reset_index 删除第三级DataFrame.reset_index drop=True:

    g = data['Event'].ne(data['Event'].shift()).cumsum()
    
    d = {'Min(Time)': ('Time', 'min'), 'Max(Time)': ('Time', 'max')}
    df = (data.groupby(['Column1','Event', g], sort=False)
              .agg(**d)
              .reset_index(level=2, drop=True)
              .reset_index())
    print (df)
      Column1 Event           Min(Time)           Max(Time)
    0   type1     A 2020-11-01 05:26:12 2020-11-01 05:26:22
    1   type1     B 2020-11-01 05:26:32 2020-11-01 05:26:37
    2   type1     A 2020-11-01 05:26:42 2020-11-01 05:26:47
    3   type1     C 2020-11-01 05:26:52 2020-11-01 05:27:02
    4   type1     B 2020-11-01 05:27:07 2020-11-01 05:27:15
    

    如果要创建辅助列:

    data['groups'] = data['Event'].ne(data['Event'].shift()).cumsum()
    print (data)
       Column1 Event                Time  groups
    0    type1     A 2020-11-01 05:26:12       1
    1    type1     A 2020-11-01 05:26:17       1
    2    type1     A 2020-11-01 05:26:22       1
    3    type1     B 2020-11-01 05:26:32       2
    4    type1     B 2020-11-01 05:26:37       2
    5    type1     A 2020-11-01 05:26:42       3
    6    type1     A 2020-11-01 05:26:47       3
    7    type1     C 2020-11-01 05:26:52       4
    8    type1     C 2020-11-01 05:27:02       4
    9    type1     B 2020-11-01 05:27:07       5
    10   type1     B 2020-11-01 05:27:15       5
    
    d = {'Min(Time)': ('Time', 'min'), 'Max(Time)': ('Time', 'max')}
    df = (data.groupby(['Column1','Event', 'groups'], sort=False)
              .agg(**d)
              .reset_index(level=2, drop=True)
              .reset_index())
    print (df)
      Column1 Event           Min(Time)           Max(Time)
    0   type1     A 2020-11-01 05:26:12 2020-11-01 05:26:22
    1   type1     B 2020-11-01 05:26:32 2020-11-01 05:26:37
    2   type1     A 2020-11-01 05:26:42 2020-11-01 05:26:47
    3   type1     C 2020-11-01 05:26:52 2020-11-01 05:27:02
    4   type1     B 2020-11-01 05:27:07 2020-11-01 05:27:15
    

    编辑:如果需要每组的下一个事件:

    df['EventEndTime'] = df.groupby('Column1')['Min(Time)'].shift(-1)
    
    #next Event not per groups
    #df['EventEndTime'] = df['Min(Time)'].shift(-1)
    
    print (df)
      Column1 Event           Min(Time)           Max(Time)        EventEndTime
    0   type1     A 2020-11-01 05:26:12 2020-11-01 05:26:22 2020-11-01 05:26:32
    1   type1     B 2020-11-01 05:26:32 2020-11-01 05:26:37 2020-11-01 05:26:42
    2   type1     A 2020-11-01 05:26:42 2020-11-01 05:26:47 2020-11-01 05:26:52
    3   type1     C 2020-11-01 05:26:52 2020-11-01 05:27:02 2020-11-01 05:27:07
    4   type1     B 2020-11-01 05:27:07 2020-11-01 05:27:15                 NaT
    

    【讨论】:

    • 事件列正在转换为数字形式,因为有很多事件,如 A、B、AA、XYZ、D 等,这造成了混乱。
    • @PriyankaS.Desai - 是的,您似乎使用['Column1', g] 而不是['Column1','Event', g]
    • @PriyankaS.Desai - 或者像data['Event'] = data['Event'].ne(data['Event'].shift()).cumsum() 一样错误地分配了后面的列,如果想重新分配使用另一列,例如data['groups'] = data['Event'].ne(data['Event'].shift()).cumsum(),然后用['Column1','Event', g] 代替['Column1','Event', 'groups']
    • 知道了,如果我还想获取事件结束时间呢? eventend 的定义是下一个事件开始的时间! shift(-1) 会起作用吗?
    • 这回答了我的问题。谢谢! :)
    猜你喜欢
    • 2014-03-18
    • 1970-01-01
    • 1970-01-01
    • 2017-07-13
    • 2020-05-27
    • 2015-12-29
    • 2016-03-20
    • 1970-01-01
    • 2019-10-18
    相关资源
    最近更新 更多