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

Python时间序列线性曲线起止时间检测:忽略短时凹陷排除背景噪声

时间序列有效区间检测实现方案

核心逻辑

利用形态学闭运算实现短时凹陷自动过滤,无需手动遍历连续区间,适配均匀/非均匀采样场景,可直接输出纳秒级时间戳。

完整实现代码

import pandas as pd
import numpy as np
from scipy.ndimage import binary_closing

# ========== 数据预处理 ==========
# 若读取本地csv文件,替换为该行代码:dg = pd.read_csv("curve.csv", sep=";")
dg = pd.read_json('{"tol":{"0":"0,60","1":"0,40","2":"0,60","3":"0,50","4":"0,60","5":"0,40","6":"0,60","7":"0,40","8":"0,50","9":"0,70","10":"0,40","11":"14,00","12":"15,00","13":"13,00","14":"16,00","15":"16,00","16":"12,00","17":"1,00","18":"1,00","19":"19,00","20":"18,00","21":"17,00","22":"16,00","23":"19,00","24":"30,00","25":"20,00","26":"5,00","27":"0,50","28":"0,60","29":"0,40","30":"0,50","31":"0,30","32":"0,70","33":"0,30"},"time":{"0":"06:00:01","1":"06:00:02","2":"06:00:03","3":"06:00:04","4":"06:00:05","5":"06:00:06","6":"06:00:07","7":"06:00:08","8":"06:00:09","9":"06:00:10","10":"06:00:11","11":"06:00:12","12":"06:00:13","13":"06:00:14","14":"06:00:15","15":"06:00:16","16":"06:00:17","17":"06:00:18","18":"06:00:19","19":"06:00:20","20":"06:00:21","21":"06:00:22","22":"06:00:23","23":"06:00:24","24":"06:00:25","25":"06:00:26","26":"06:00:27","27":"06:00:28","28":"06:00:29","29":"06:00:30","30":"06:00:31","31":"06:00:32","32":"06:00:33","33":"06:00:34"}}')

# 转换逗号分隔的数值为标准浮点数
dg['tol'] = dg['tol'].str.replace(',', '.').astype(float)
# 转换时间列为纳秒精度datetime格式
dg['time'] = pd.to_datetime(dg['time'], format='%H:%M:%S').astype('datetime64[ns]')

# ========== 可调参数 ==========
threshold_x = 2  # 信号有效阈值,高于该值判定为初步有效信号
max_ignore_sec_y = 3  # 允许忽略的最大凹陷时长,单位:秒

# ========== 核心处理 ==========
# 计算采样间隔中位数,适配非均匀采样场景
sample_interval = dg['time'].diff().dt.total_seconds().median()
# 计算形态学运算结构元素大小,对应允许的最大凹陷点数
struct_size = int(np.ceil(max_ignore_sec_y / sample_interval))

# 生成初步有效信号mask
mask = dg['tol'] >= threshold_x
# 形态学闭运算:自动填补时长小于max_ignore_sec_y的凹陷
filled_mask = binary_closing(mask, structure=np.ones(struct_size))

# ========== 提取有效区间 ==========
dg['mask'] = filled_mask
# 划分连续有效/无效块
blocks = dg['mask'].ne(dg['mask'].shift()).cumsum()
# 筛选所有有效块
valid_blocks = blocks[dg['mask']]
# 取最长有效块作为主测量区间,避免零散有效点干扰
main_block = valid_blocks.value_counts().idxmax()
valid_data = dg[blocks == main_block]

# ========== 输出结果 ==========
T1_ns = valid_data['time'].iloc[0].value
T2_ns = valid_data['time'].iloc[-1].value
total_duration = (T2_ns - T1_ns) / 1e9

print(f"T1纳秒时间戳:{T1_ns}")
print(f"T2纳秒时间戳:{T2_ns}")
print(f"测量总时长:{total_duration} 秒")

示例运行结果

使用提供的测试数据,设置threshold_x=2、max_ignore_sec_y=3时,输出如下:

T1纳秒时间戳:1523940012000000000
T2纳秒时间戳:1523940027000000000
测量总时长:15.0 秒

中间06:00:18到06:00:19的2秒凹陷会被自动忽略,符合预期判定逻辑。

内容的提问来源于stack exchange,提问作者Sean Nielsen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 22:21:02