【问题标题】:Find the last sequence of occurance of a value in a time series data in pandas在熊猫的时间序列数据中查找值的最后出现序列
【发布时间】:2020-09-18 02:38:30
【问题描述】:

我有 10 天的每分钟时间序列数据,包含三列:time stampcategoryalarm。给定一个日期,我想在groupby 类别中找到在给定日期之前连续将警报设置为1 的timestamps,并从该子集中创建一个dataframe

   'Category'       'Date'              'Alarm'
0      A        1999-11-10 12:01:00        1
1      A        1999-11-10 12:02:00        1
2      A        1999-11-10 12:03:00        1
3      A        1999-11-10 12:04:00        1
4      A        1999-11-10 12:05:00        0
5      A        1999-11-10 12:06:00        0
.
.
.
1101   A        1999-11-13 10:07:00        1
1102   A        1999-11-13 10:08:00        1
1103   A        1999-11-13 10:09:00        1
1104   B        1999-11-23 13:09:00        0
1105   B        1999-11-23 13:10:00        0
1106   B        1999-11-23 13:11:00        1
1107   B        1999-11-23 13:12:00        1
1108   B        1999-11-23 13:13:00        1
1109   B        1999-11-23 13:14:00        0
.
.
.
. 
2110   B        1999-11-26 13:13:00        0
2110   B        1999-11-26 13:14:00        0
2110   B        1999-11-26 13:15:00        1 
2111   B        1999-11-26 13:16:00        1 
2112   B        1999-11-26 13:17:00        1 
2113   B        1999-11-26 13:18:00        1 
2114   B        1999-11-26 13:19:00        1
2115   B        1999-11-26 13:20:00        0
2116   B        1999-11-26 13:21:00        0
2117   C        1999-12-02 17:11:00        1 
.
.    
.

我希望输出是一个只有这些行的新数据框:

     'Category'       'Date'              'Alarm'
 1101   A        1999-11-13 10:07:00        1
 1102   A        1999-11-13 10:08:00        1
 1103   A        1999-11-13 10:09:00        1
 2110   B        1999-11-23 13:15:00        1 
 2111   B        1999-11-23 13:16:00        1 
 2112   B        1999-11-23 13:17:00        1 
 2113   B        1999-11-23 13:18:00        1 
 2114   B        1999-11-23 13:19:00        1

即每组中最后一个连续的 1 序列处于警报状态的行。 我尝试过的:

df.groupby('category')['alarm'].apply(lambda x: x==1)

但这会给出所有警报为 1 的行,而不仅仅是连续 1 的最后一个序列。任何有关如何获得此值的说明都将受到赞赏。谢谢! :)

编辑 1:我只是提供了数据帧的一个子集。最后一个连续的 1 序列可以发生在任意天数之前(例如,如果时间序列是从 11 月 1 日到 11 月 10 日,对于一个类别,最后一个连续的 1可能发生在 11 月 2 日或 11 月 8 日。而且 1 的长度也可能不同。

【问题讨论】:

    标签: python pandas time-series


    【解决方案1】:

    我们试试

    # convert to datetime type
    df.Date = pd.to_datetime(df.Date)
    
    # blocks of consecutive `1`:
    s = (1-df.Alarm).cumsum()*df.Alarm
    
    # last group of `1` within Category and day:
    last_groups = s.groupby(df.Category).transform('max')
    
    # output:
    df[s==last_groups]
    

    输出:

         Category                Date  Alarm
    1101        A 1999-11-13 10:07:00      1
    1102        A 1999-11-13 10:08:00      1
    1103        A 1999-11-13 10:09:00      1
    2110        B 1999-11-26 13:15:00      1
    2111        B 1999-11-26 13:16:00      1
    2112        B 1999-11-26 13:17:00      1
    2113        B 1999-11-26 13:18:00      1
    2114        B 1999-11-26 13:19:00      1
    2117        C 1999-12-02 17:11:00      1
    

    【讨论】:

    • 绝妙的答案,非常好!
    • 我不相信最后一行属于输出但是
    • 谢谢!但这也提取了之前的连续序列,而不仅仅是最后一个。我不是每天都在寻找连续的 1,只是在最后一个序列出现时。它可以在任意天数之前。
    • df.date.normalized放到groupby里面,你应该得到每个id的一个序列。
    • 我仍然得到相同的结果。你能解释一下代码吗?
    【解决方案2】:
    # Make date into datetime
    df['Date'] = pd.to_datetime(df['Date'])
    # Get rid of time part
    df['Day'] = df['Date'].dt.strftime('%Y-%m-%d')
    
    # Taking rolling sum of Alarms
    k = df.groupby('Day')['Alarm'].rolling(3).sum().reset_index()
    # Take last set of consecutive 3's per day
    k = k[k['Alarm']==3].groupby('Day').last()
    # Capture the index of each row in the original data frame
    k = k['level_1'].values
    # Drop day column
    df.drop(columns=['Day'], inplace=True)
    # Join the rows together
    df = pd.concat([df.loc[x-2:].head(3) for x in k])
    

    输出

     Category                Date  Alarm
    6         A 1999-11-10 12:07:00      1  
    7         A 1999-11-10 12:08:00      1  
    8         A 1999-11-10 12:09:00      1 
    15        B 1999-11-23 13:15:00      1 
    16        B 1999-11-23 13:16:00      1  
    17        B 1999-11-23 13:17:00      1  
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-28
      • 2019-06-18
      • 1970-01-01
      相关资源
      最近更新 更多