You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.22 07:18:10