如何使用Pandas识别机器启停周期并过滤异常脏数据
实现方案
最简快速实现
用中值滤波直接处理状态序列即可自动过滤短片段的异常值,几行代码就能完成需求:
import pandas as pd from scipy.signal import medfilt # 示例数据 Machine = [0,0,0,0,0,0,1,1,1,1,1,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0] df2 = pd.DataFrame(Machine) # kernel_size设为3可以过滤连续长度为1的异常0,设为5可过滤连续长度<=2的异常0,以此类推(需为奇数) df2['fixed_status'] = medfilt(df2[0], kernel_size=3).astype(int) # 开机周期数:0→1的跳变次数 start_cnt = ((df2['fixed_status'] == 1) & (df2['fixed_status'].shift() == 0)).sum() # 关机周期数:1→0的跳变次数 stop_cnt = ((df2['fixed_status'] == 0) & (df2['fixed_status'].shift() == 1)).sum() print(f"开机周期总数:{start_cnt}") print(f"关机周期总数:{stop_cnt}")
运行后输出结果与你预期一致:
开机周期总数:3 关机周期总数:4
自定义可控实现
如果需要更灵活的控制过滤规则(比如单独针对0值过滤,不影响正常的短1片段),可以用连续状态分组的方案:
核心思路
先对连续状态分组,将长度小于预设阈值的异常0段(运行过程中混入的错误数据)替换为1,再基于修正后的状态序列统计启停周期数即可。
完整代码
import pandas as pd # 示例数据 Machine = [0,0,0,0,0,0,1,1,1,1,1,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0] df2 = pd.DataFrame(Machine, columns=['status']) # 1. 给连续相同状态的段打分组标签 df2['group'] = df2['status'].ne(df2['status'].shift()).cumsum() # 2. 计算每个分组的长度和对应状态 group_info = df2.groupby('group').agg( status=('status', 'first'), length=('status', 'count') ).reset_index() # 3. 设定异常0段的最大长度阈值,这里设为2,即连续长度<2的0都判定为坏数据 max_error_zero_len = 2 # 找出需要替换为1的异常0分组 bad_zero_groups = group_info.loc[(group_info['status']==0) & (group_info['length']<max_error_zero_len), 'group'] # 修正状态 df2['fixed_status'] = df2.apply(lambda x: 1 if x['group'] in bad_zero_groups.values else x['status'], axis=1) # 4. 统计开机、关机周期数 start_count = ((df2['fixed_status'] == 1) & (df2['fixed_status'].shift(1) == 0)).sum() stop_count = ((df2['fixed_status'] == 0) & (df2['fixed_status'].shift(1) == 1)).sum() print(f"开机周期总数:{start_count}") print(f"关机周期总数:{stop_count}")
内容的提问来源于stack exchange,提问作者SeanK22
相关产品推荐
相关产品推荐

