【问题标题】:How to find occurrence of consecutive events in python timeseries data frame?如何在python时间序列数据框中查找连续事件的发生?
【发布时间】:2023-03-12 07:15:01
【问题描述】:

我有一个带有 datevalue 列的气象观测时间序列:

df = pd.DataFrame({'date':['11/10/2017 0:00','11/10/2017 03:00','11/10/2017 06:00','11/10/2017 09:00','11/10/2017 12:00',
                           '11/11/2017 0:00','11/11/2017 03:00','11/11/2017 06:00','11/11/2017 09:00','11/11/2017 12:00',
                          '11/12/2017 00:00','11/12/2017 03:00','11/12/2017 06:00','11/12/2017 09:00','11/12/2017 12:00'],
                  'value':[850,np.nan,np.nan,np.nan,np.nan,500,650,780,np.nan,800,350,690,780,np.nan,np.nan],                   
                   'consecutive_hour': [ 3,0,0,0,0,3,6,9,0,3,3,6,9,0,0]})

有了这个DataFrame,我想要consecutive_hours的第三列,这样如果特定时间戳中的值小于1000,我们在“3:00”的“连续小时”中给出相应的值" 小时并找到连续的此类事件,如 6:00 9:00 如上所述。

最后,我想汇总计算连续小时数发生次数和天数的表格,以便汇总表格如下所示:

df_summary = pd.DataFrame({'consecutive_hours':[3,6,9,12],
                      'number_of_day':[2,0,2,0]})

我尝试了几种在线解决方案和方法,如 shift()、diff() 等,如:How to groupby consecutive values in pandas DataFrame

还有更多,花了几天但还没有运气。

非常感谢您在此问题上的帮助。 谢谢!

【问题讨论】:

  • consecutive_hour 列是预期结果吗?如果是,请解释一下为什么2017-11-11 06:00:0012 2017-11-12 06:00:00 是9 而2017-11-10 06:00:00 是0。
  • Yes Continuous_hour 列是预期结果。
  • 是的,continuous_hour 列是预期结果。 2017-11-11 06:00:00 是 9,因为如果您查看值列,您会看到值:500,650 和 780 在三行中连续出现,直到时间戳 2017-11-11 06:00:00 .同样的逻辑适用于 2017-11-12 06:00:00。并且 2017-11-10 06:00:00 具有 0 连续小时 值,因为在此时间戳和 2017-11-10 03:00:00 中有 Nan 值。
  • 您确定df_summary 吗?我找到了{3: 3, 6: 2, 9: 2, 12: 0}
  • 是的,这就像:consecutive_hour == 3(单独)发生在 2017-11-10 00:00:00 和 2017:11:11 12:00:00对于不同的一天,计数 3 连续小时 等于 2。2017 年 11 月 11 日和 2017 年 11 月 12 日的最高连续值为 9,同样使 9 的计数等于 2。没有一天有**连续时间**最高的 6 小时或 12 小时;所以它们等于 0。

标签: python pandas


【解决方案1】:

输入数据:

>>> df
                  date  value
0  2017-11-10 00:00:00  850.0
1  2017-11-10 03:00:00    NaN
2  2017-11-10 06:00:00    NaN
3  2017-11-10 09:00:00    NaN
4  2017-11-10 12:00:00    NaN
5  2017-11-11 00:00:00  500.0
6  2017-11-11 03:00:00  650.0
7  2017-11-11 06:00:00  780.0
8  2017-11-11 09:00:00    NaN
9  2017-11-11 12:00:00  800.0
10 2017-11-12 00:00:00  350.0
11 2017-11-12 03:00:00  690.0
12 2017-11-12 06:00:00  780.0
13 2017-11-12 09:00:00    NaN
14 2017-11-12 12:00:00    NaN

cumcount_reset函数改编自@jezraelanswer
Python pandas cumsum with reset everytime there is a 0

cumcount_reset = \
    lambda b: b.cumsum().sub(b.cumsum().where(~b).ffill().fillna(0)).astype(int)

df["consecutive_hour"] = (df.set_index("date")["value"] < 1000) \
       .groupby(pd.Grouper(freq="D")) \
       .apply(lambda b: cumcount_reset(b)).mul(3) \
       .reset_index(drop=True)

输出结果:

>>> df
                  date  value  consecutive_hour
0  2017-11-10 00:00:00  850.0                 3
1  2017-11-10 03:00:00    NaN                 0
2  2017-11-10 06:00:00    NaN                 0
3  2017-11-10 09:00:00    NaN                 0
4  2017-11-10 12:00:00    NaN                 0
5  2017-11-11 00:00:00  500.0                 3
6  2017-11-11 03:00:00  650.0                 6
7  2017-11-11 06:00:00  780.0                 9
8  2017-11-11 09:00:00    NaN                 0
9  2017-11-11 12:00:00  800.0                 3
10 2017-11-12 00:00:00  350.0                 3
11 2017-11-12 03:00:00  690.0                 6
12 2017-11-12 06:00:00  780.0                 9
13 2017-11-12 09:00:00    NaN                 0
14 2017-11-12 12:00:00    NaN                 0

汇总表

df_summary = df.loc[df.groupby(pd.Grouper(key="date", freq="D"))["consecutive_hour"] \
                      .apply(lambda h: (h - h.shift(-1).fillna(0)) > 0), 
                    "consecutive_hour"] \
               .value_counts().reindex([3, 6, 9, 12], fill_value=0) \
               .rename("number_of_day") \
               .rename_axis("consecutive_hour") \
               .reset_index()
>>> df_summary
   consecutive_hour  number_of_day
0                 3              2
1                 6              0
2                 9              2
3                12              0

【讨论】:

  • @Corralien,我非常感谢你。你真的拯救了我的一天。你能帮我解决我问题的第二部分吗?我也需要找到汇总表:df_summary = pd.DataFrame({'consecutive_hours':[3,6,9,12], 'number_of_day':[2,0,2,0]})
  • 如果答案对您有帮助而您还没有帮助,请不要忘记投票。
  • 再次感谢@Corralien。工作得很好。很大的帮助。高度赞赏。我投了赞成票。
  • ~@ Corralien~ 我已经发布了新问题:stackoverflow.com/questions/67333038/…,我也很高兴收到您的意见。谢谢
猜你喜欢
  • 1970-01-01
  • 2013-11-27
  • 1970-01-01
  • 2019-10-09
  • 2015-01-10
  • 2010-09-20
  • 2018-12-18
  • 2023-03-07
  • 1970-01-01
相关资源
最近更新 更多