获取多索引熊猫系列关卡中序列的第一个和最后一个元素



我有一个系列,它的状态可以是真或假。它有一个 MultiIndex,第一级用于 ID,第二级用于每个 ID 中的一集,第三级用于记录状态的日期。

ID  Episode Date        Status
foo 1       2019-02-01  False
            2019-02-02  True
            2019-02-03  True
            2019-02-04  False
    2       2019-02-05  True
            2019-02-06  True
            2019-02-07  False
    3       2019-02-08  False
            2019-02-09  True
            2019-02-10  True
bar 1       2019-03-03  False
            2019-03-04  True
    2       2019-03-05  True
            2019-03-06  True
            2019-03-07  False
            2019-03-08  True
            2019-03-09  False

我想将剧集中的状态开始为真以及何时停止为真提取到数据帧。对于此示例,结果应如下所示:

 ID Episode Start Dates             End Dates       
foo 1       2019-02-02              2019-03-03          
    2       2019-02-05              2019-02-06  
    3       2019-02-09              2019-02-10
bar 1       2019-03-04              2019-03-04
    2       2019-03-05, 2019-03-08  2019-03-06, 2019-03-08

检查使用 groupbycumsum组创建内部键,下一步我们根据 df 中的所有True值进行过滤,然后我们使用新键和first last进行另一轮groupbyjoin结果

s=(~df.Status).groupby(level=['ID','Episode']).cumsum().reset_index()
s[df.Status.values].groupby(['ID','Episode','Status'])['Date'].agg(['first','last']).groupby(level=[0,1]).agg(','.join)
Out[104]: 
                             first                   last
ID  Episode                                              
bar 1                   2019-03-04             2019-03-04
    2        2019-03-05,2019-03-08  2019-03-06,2019-03-08
foo 1                   2019-02-02             2019-02-03
    2                   2019-02-05             2019-02-06
    3                   2019-02-09             2019-02-10
您还可以

使用将Status列移动一pandas.Series.shift

df['prev_Status'] = df['Status'].shift(1)
df['next_Status'] = df['Status'].shift(-1)
                    Status  prev_Status next_Status
Date            
foo 1   2019-02-01  False   NaN     True
        2019-02-02  True    False   True
        2019-02-03  True    True    False
        2019-02-04  False   True    True
2       2019-02-05  True    False   True
        2019-02-06  True    True    False

一旦移位,您可以在打开True时按预期进行查询

df.query('prev_Status=="False"').query('Status=="True"').groupby(level=[0,1]).Date.agg(','.join)
bar  1    2019-03-04
     2    2019-03-08
foo  1    2019-02-02
     2    2019-02-05
     3    2019-02-09
Name: Date, dtype: object

或者何时关闭

df.query('Status=="True"').query('next_Status=="False"').groupby(level=[0,1]).Date.agg(','.join)
bar  2    2019-03-06,2019-03-08
foo  1               2019-02-03
     2               2019-02-06
     3               2019-02-10
Name: Date, dtype: object

有人可能会争辩说,这比另一个(非常好(答案效率低,但更容易理解

最新更新