基于Pandas的时长条件校验:限制功率列连续同值时长不超过5分钟
基于Pandas的时长条件校验:限制功率列连续同值时长不超过5分钟
嘿,我完全懂你的困扰!滚动窗口的mean()或sum()确实没法精准识别连续同值的时长——它们只看固定窗口里的统计值,根本不管窗口内的数值是不是连续的。要解决这个问题,得换个思路:先把连续相同功率值的行分成独立的“块”,再判断每个块的持续时长是否超过5分钟,最后对超限的块做针对性处理。
下面是一步步的实现方案,完全贴合你的DataFrame结构来讲解:
第一步:确保索引是datetime类型
首先得确认你的DataFrame索引是datetime64类型,这样才能准确计算时长:
# 如果索引还不是datetime类型,先转换 df.index = pd.to_datetime(df.index)
第二步:标记连续同值的分组
我们需要给每一段连续相同的功率值分配唯一的分组ID,这样就能单独追踪每个块的时长:
# 当功率值和前一行不同时,生成新的分组ID df['group_id'] = (df['Power[kW]'].diff() != 0).cumsum()
举个例子:如果第1-3行是1000,第4行是0,第5-10行是-1000,它们的group_id会分别是1、2、3,完美区分每一段连续值。
第三步:筛选出超限的分组
接下来统计每个分组的关键信息,找出持续时长超过5分钟(300秒)且功率为±1000的分组:
# 计算每个分组的开始时间、结束时间、持续时长和功率值 group_stats = df.groupby('group_id').agg( start_time=('Power[kW]', lambda x: x.index[0]), end_time=('Power[kW]', lambda x: x.index[-1]), duration=('Power[kW]', lambda x: (x.index[-1] - x.index[0]).total_seconds()), power_value=('Power[kW]', 'first') ) # 筛选出符合超限条件的分组 over_limit_groups = group_stats[ (group_stats['duration'] > 300) & (group_stats['power_value'].isin([1000, -1000])) ]
第四步:处理超限的分组
这一步取决于你想要的业务逻辑,这里给两种常见的处理方式:
方式1:保留前5分钟的有效值,超出部分设为0
比如某块连续1000持续了6分钟,我们只保留前5分钟的1000,剩下的1分钟设为0:
for idx, row in over_limit_groups.iterrows(): # 计算前5分钟的截止时间 cutoff_time = row['start_time'] + pd.Timedelta(seconds=300) # 修改分组内超过截止时间的行的功率值 df.loc[(df['group_id'] == idx) & (df.index > cutoff_time), 'Power[kW]'] = 0
方式2:直接把整个超限分组的功率设为0
如果只要连续时长超过5分钟,就把整个块的功率都改成0:
# 获取所有超限分组的ID over_limit_ids = over_limit_groups.index # 批量修改这些分组的功率值 df.loc[df['group_id'].isin(over_limit_ids), 'Power[kW]'] = 0
为什么这个方法比滚动窗口靠谱?
滚动窗口是“固定窗口滑动”,它无法区分窗口内的数值是连续同值还是断断续续的。而分组的方式是“追踪连续块”,能精准计算每一段相同功率的持续时间,完全匹配你的需求。
最后,如果你不需要保留group_id列,处理完之后可以删掉它:
df.drop('group_id', axis=1, inplace=True)
备注:内容来源于stack exchange,提问作者user9667136
相关产品推荐
相关产品推荐

