python - 如何在python时间序列数据框中找到连续事件的发生?
问题描述
我有一个带有日期和值列的气象观测时间序列:
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,我想要第三列连续时间,这样如果特定时间戳中的值小于 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() 等,如:如何在 pandas DataFrame 中对连续值进行分组
还有更多,花了几天但还没有运气。
我非常感谢在这个问题上的帮助。谢谢!
解决方案
输入数据:
>>> 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
函数改编自@jezrael的这个答案: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
推荐阅读
- android - 如何创建一个导航抽屉布局,该布局分别接受用户输入并在单击按钮时执行计算?
- macros - SAS:如何引用全局宏变量来创建新表或数据集?
- unit-testing - Mockito 不能模拟/监视,因为最终类
- wordpress - 使用 Wordpress 插件临时禁用客户端 gtag (Google Analytics)
- mysql - MySQL - 将缺失的日期记录添加到表中
- c# - 尝试使用 LINQ 在 XML 文件中检索值
- java - 以流形式访问 StringWriter 内容
- ruby - 如何检查文件是否仍被当前线程锁定?
- javascript - 以数组的形式存储来自附加表单数据的 php 变量
- batch-file - 从修剪后的文件中覆盖同名文件