如何用Matlab实现Bernaola Galvan分割算法去除时序数据无效段
批量处理加工数据:BG分割算法实现及替代方案
一、Bernaola Galvan(BG)分割算法实现
BG算法核心是通过方差分析识别数据序列中的突变点,适合区分刀具未接触(趋近于0)和接触(非0)的阶段。以下是基于Python的落地方案,依赖ruptures时间序列分割库和numpy:
步骤1:安装依赖
pip install ruptures numpy pandas
步骤2:代码实现
import numpy as np import pandas as pd import ruptures as rpt def remove_zero_segments_with_bg(data, threshold=1e-3, n_bkps=1): """ 用BG算法移除趋近于0的数据段 :param data: 1D加工数据数组 :param threshold: 判断"趋近于0"的阈值 :param n_bkps: 预设突变点数量(单启停场景设为1即可) :return: 过滤后的加工数据数组 """ # 基于方差的BG分割逻辑 model = rpt.Binseg(model="l2") model.fit(data) breakpoints = model.predict(n_bkps=n_bkps) # 拆分数据段并判断是否为有效加工段 segments = [] start = 0 for bkp in breakpoints: segment = data[start:bkp] segments.append((np.mean(np.abs(segment)), start, bkp)) start = bkp # 筛选保留均值大于阈值的段 filtered_data = [] for mean_val, s, e in segments: if mean_val > threshold: filtered_data.extend(data[s:e]) return np.array(filtered_data) # 批量处理示例 # 假设数据按列存储在csv中,每列对应一条加工曲线 df = pd.read_csv("processing_data.csv") processed_cols = [] for col in df.columns: raw_data = df[col].values processed_data = remove_zero_segments_with_bg(raw_data) # 对齐长度(补NaN避免结构错乱) padded_data = np.full(len(raw_data), np.nan) padded_data[:len(processed_data)] = processed_data processed_cols.append(padded_data) df_processed = pd.DataFrame(np.array(processed_cols).T, columns=[f"{col}_processed" for col in df.columns]) pd.concat([df, df_processed], axis=1).to_csv("processed_data.csv", index=False)
注意事项
- 若存在多次启停,可调整
n_bkps参数增加突变点数量; - 原始数据含噪声时,可先做平滑处理:
data = np.convolve(data, np.ones(5)/5, mode="same"),提升分割准确性。
二、更优替代方案
BG算法适合复杂突变场景,但针对"趋近于0"的简单需求,以下方案效率更高:
1. 阈值过滤法(推荐)
直接设定阈值过滤连续低幅值段,代码简洁、运行速度快,适合批量处理:
def filter_zero_segments_by_threshold(data, threshold=1e-3, min_length=10): """ 阈值法移除趋近于0的连续段 :param min_length: 最小连续段长度,避免误删噪声点 :return: 过滤后的数据 """ mask = np.abs(data) > threshold # 定位连续有效段的起止索引 diff = np.diff(np.concatenate([[0], mask.astype(int), [0]])) starts = np.where(diff == 1)[0] ends = np.where(diff == -1)[0] filtered_data = [] for s, e in zip(starts, ends): if e - s >= min_length: filtered_data.extend(data[s:e]) return np.array(filtered_data)
2. 滑动窗口方差法
通过检测窗口内方差突变,判断加工阶段的起始点:
def filter_by_sliding_window(data, window_size=20, var_threshold=1e-4): """ 滑动窗口方差法过滤数据 """ variances = np.convolve(data**2, np.ones(window_size)/window_size, mode="valid") # 找到方差首次超过阈值的位置 start_idx = np.argmax(variances > var_threshold) # 保留加工阶段数据 return data[start_idx + window_size//2:]
方案选择建议
- 若0段与加工段过渡模糊(存在渐变区),优先用BG算法;
- 若两段边界清晰,阈值法是最优选择,兼顾效率与准确性。
内容的提问来源于stack exchange,提问作者Zhiqiang Liu
相关产品推荐
相关产品推荐

