如何将pandas时间序列DF按1/4/8小时等间隔分组并获取最小值对应时间戳
实现方案
前置准备
先确保timestamp字段为datetime类型,过滤掉水流量为空的异常数据:
import pandas as pd # 转换时间字段格式 df['timestamp'] = pd.to_datetime(df['timestamp']) # 过滤空值 df = df.dropna(subset=['waterFlowRate'])
方法1:resample + idxmin(推荐)
resample结合idxmin()方法可以直接返回每个时间分组内最小值对应的原始行索引,而非分组起始时间,再用索引取原数据即可得到完整原始时间戳:
# 自定义时间间隔,支持1H/4H/8H等任意pandas支持的时间频率 target_freq = '1H' # 1. 将timestamp设为时间索引 df_indexed = df.set_index('timestamp') # 2. 取每个分组水流量最小值对应的原始索引 min_time_idx = df_indexed.resample(target_freq)['waterFlowRate'].idxmin() # 3. 从原始数据中提取最小值对应的完整行 min_value_rows = df_indexed.loc[min_time_idx].reset_index()
此时min_value_rows中的timestamp字段就是每个分组内最小值对应的原始采集时间。
方法2:groupby + pd.Grouper(无需修改原DF结构)
如果不想改动原始DataFrame的索引,可通过pd.Grouper指定分组时间字段和频率:
target_freq = '4H' # 按指定时间间隔分组,取每个分组最小值对应的行索引 min_time_idx = df.groupby(pd.Grouper(key='timestamp', freq=target_freq))['waterFlowRate'].idxmin() # 提取对应行 min_value_rows = df.loc[min_time_idx].reset_index(drop=True)
同分组多最小值处理
如果单个时间分组内存在多个相同的最小值,上述方法只会返回第一个出现的最小值行,如需保留所有符合条件的行可使用以下写法:
target_freq = '8H' # 生成每个行对应的分组标识 df['group_tag'] = df['timestamp'].dt.floor(target_freq) # 取每个分组的最小值 group_min_val = df.groupby('group_tag')['waterFlowRate'].transform('min') # 筛选所有等于分组最小值的行 all_min_rows = df[df['waterFlowRate'] == group_min_val].reset_index(drop=True)
最小值出现规律判断
拿到所有最小值对应的原始时间后,提取分钟字段统计频次即可判断是否存在固定出现规律:
# 提取最小值对应的分钟数 all_min_rows['occur_minute'] = all_min_rows['timestamp'].dt.minute # 统计各分钟的出现次数占比 minute_stat = all_min_rows['occur_minute'].value_counts(normalize=True) # 设定规律判定阈值,比如出现占比超过90%则认为是固定规律 threshold = 0.9 top_minute = minute_stat.index[0] top_rate = minute_stat.iloc[0] if top_rate >= threshold: print(f"水流量最小值稳定出现在每小时的第{top_minute}分钟,出现占比{top_rate:.1%}") # 此处添加需要执行的指定操作逻辑
内容的提问来源于stack exchange,提问作者Galaxy
相关产品推荐
相关产品推荐

