前言环保在线监测系统每天会产生大量数据例如废气流量、颗粒物浓度、二氧化硫浓度、氮氧化物浓度、污水流量、化学需氧量、氨氮、pH值以及设备运行状态等。这些数据通常会经过采集仪器、数据采集传输设备、网络和管理平台等多个环节。任何一个环节出现传感器故障、通信中断、设备维护或数据解析错误都可能产生异常值。生态环境部发布的污染物自动监测相关技术要求对自动监测设备的数据采集、处理和传输进行了规范相关数据标记规则也强调应根据设备运行和生产工况对异常监测数据进行如实标记而不是简单删除。因此在开发环保数据平台时异常数据处理不能只写一句ifvaluelimit:alarm()一个相对完整的数据质量判断过程至少需要回答三个问题当前数据是否超出仪器量程当前数据是否与历史变化规律明显不符异常来自污染物变化还是来自设备、通信或生产工况一、环保监测数据中常见的异常类型1. 固定异常值部分设备在故障或通信中断时可能持续返回固定值例如0 -1 9999 65535这些数值不一定代表真实监测结果可能只是设备定义的故障码或默认填充值。在系统接入阶段应根据设备通信协议建立异常码字典避免把故障码直接写入监测数据库。INVALID_CODES{-1,9999,65535}defis_invalid_code(value):returnvalueinINVALID_CODES需要注意的是数值为零并不一定异常。某些污染物在特定工况下可能接近零因此不能在缺少业务背景的情况下把所有零值都判断为无效数据。2. 超量程数据每个监测仪器都有对应的测量范围。例如某个传感器的有效量程为0至500系统却接收到860则需要检查数据单位是否转换错误仪器量程是否发生调整通信报文是否解析错误现场浓度是否确实超过量程设备是否处于校准或维护状态。可以先使用简单规则进行初步标记defcheck_range(value,min_value,max_value):ifvalueisNone:returnMISSINGifvaluemin_valueorvaluemax_value:returnOUT_OF_RANGEreturnNORMAL这里建议使用“标记”而不是“删除”。原始数据应尽量保留处理后的有效数据可以另行存储。3. 数据长时间不变化正常环境数据通常会存在一定波动。如果某个监测值连续数小时完全相同可能意味着传感器冻结、通信缓存未更新或设备停止采样。defis_frozen(values,min_count10):iflen(values)min_count:returnFalserecent_valuesvalues[-min_count:]returnlen(set(recent_values))1但固定值也不能直接等同于设备故障。例如生产设备停机后部分监测参数可能长时间保持稳定。因此还需要结合生产状态、治理设施状态和设备状态综合判断。4. 突然跳变假设某项污染物浓度在一分钟内从20变化到480下一分钟又恢复到22这种数据可能来自瞬时干扰、设备反吹、校准操作或解析错误。最基础的跳变判断可以使用相邻差值defdetect_jump(previous_value,current_value,threshold):ifprevious_valueisNoneorcurrent_valueisNone:returnFalsereturnabs(current_value-previous_value)threshold不过固定差值阈值不适用于所有数据。对于正常值较小、波动比例较大的参数可以同时判断变化比例defdetect_relative_jump(previous_value,current_value,ratio3):ifprevious_valuein(None,0)orcurrent_valueisNone:returnFalsechange_ratioabs(current_value-previous_value)/abs(previous_value)returnchange_ratioratio二、使用滑动窗口识别异常只比较相邻两个数据点容易受到偶然波动影响。更常见的做法是使用滑动窗口根据最近一段时间的数据计算均值和标准差。importstatisticsdefdetect_by_zscore(history,current_value,window_size20,z_limit3):ifcurrent_valueisNone:returnMISSINGwindowhistory[-window_size:]iflen(window)5:returnINSUFFICIENT_DATAmean_valuestatistics.mean(window)std_valuestatistics.pstdev(window)ifstd_value0:returnFROZEN_REFERENCEz_scoreabs(current_value-mean_value)/std_valueifz_scorez_limit:returnSTATISTICAL_ANOMALYreturnNORMAL这种方法适合识别偏离近期趋势的数据但也存在局限。当企业切换生产工况、启停生产设备或调整治理设施时监测数据可能出现合理变化。如果系统只依据统计模型就可能产生大量误报。因此统计异常只能说明“当前值与近期数据不同”不能直接说明“当前排放异常”。三、将设备状态与监测数据结合环保监测平台不应只保存污染物数值还应同步保存设备和工况信息例如生产设施状态 污染治理设施状态 采样设备状态 分析仪状态 数据采集仪状态 校准状态 维护状态 网络连接状态可以为每条监测数据建立统一的数据结构monitoring_record{timestamp:2026-07-29 10:30:00,point_code:STACK01_SO2,value:28.6,unit:mg/m3,production_status:RUNNING,treatment_status:RUNNING,instrument_status:NORMAL,network_status:ONLINE,data_flag:NORMAL}当数据出现跳变时系统可以先检查仪器状态defclassify_record(record,min_value,max_value):valuerecord.get(value)ifrecord.get(network_status)OFFLINE:returnCOMMUNICATION_EXCEPTIONifrecord.get(instrument_status)MAINTENANCE:returnMAINTENANCE_DATAifvalueisNone:returnMISSINGifvaluemin_valueorvaluemax_value:returnOUT_OF_RANGEreturnNORMAL这种处理方式比单纯判断浓度是否超过某个数值更可靠。生态环境监测数据管理强调数据的真实、准确、完整和有效。发现自动监测设备传输数据异常时相关单位还需要检查设备运行状态并进行处理。四、原始数据和修正数据应分开保存在实际项目中不建议直接修改原始监测值。可以采用三层数据结构第一层原始数据保存设备上传的原始报文和原始数值不进行人工修改。第二层标准化数据完成字段映射、单位换算、时间格式转换和设备编码统一。第三层业务数据增加数据质量标记、异常原因、审核状态和统计结果。示例字段如下raw_value设备原始值 standard_value单位转换后的数值 quality_flag数据质量标记 exception_reason异常原因 review_status审核状态 review_user审核人员 review_time审核时间通过这种方式可以追溯数据从接收到处理的完整过程也能避免异常识别程序覆盖原始记录。五、异常数据处理的几个建议第一不要把“异常值”和“超标值”混为一谈。异常值通常指数据质量或设备运行存在疑问超标值则需要依据适用的排放标准和具体工况判断。第二不要发现异常后直接删除数据。更合理的方式是保留原始数据并增加无效、维护、故障、缺失或待审核等标记。第三不要只依赖单一算法。量程判断、变化率、滑动窗口、设备状态和人工审核应相互补充。第四应为异常规则设置版本号。规则调整后需要知道历史数据是依据哪个版本处理的。第五系统告警需要设置恢复机制。人员点击“已确认”不代表数据已经恢复正常告警确认时间和告警结束时间应分别记录。总结环保在线监测系统中的异常识别本质上不是简单的数据清洗而是监测仪器、通信协议、生产工况和软件规则之间的协同判断。一套可维护的处理流程通常包括接收原始数据 ↓ 检查报文完整性 ↓ 识别故障码和缺失值 ↓ 判断量程与变化趋势 ↓ 关联生产及设备状态 ↓ 生成数据质量标记 ↓ 保留原始记录并进入审核流程Python可以完成范围判断、趋势分析和异常分类但算法只能辅助发现问题。最终的数据有效性判断还需要结合监测方法、设备运行记录和现场实际工况。对于环保数据平台而言真正重要的不是把所有异常数据“清理干净”而是让每一条异常数据都有来源、有标记、有处理过程并且能够被追溯。