Pandas递归剔除每行超出均值±3%的异常值实现求助
逐次剔除传感器温度异常值的实现方案
针对你的需求,这里提供基于Python Pandas的实现方案,核心逻辑是按时间分组后循环剔除偏差最大的异常值,直到所有剩余数据落在当前均值的±3%范围内。
核心处理逻辑
对每个5分钟时间间隔的传感器数据,重复执行以下步骤:
- 计算当前剩余温度值的均值
- 计算每个值与当前均值的相对偏差百分比:
|(值 - 均值)/均值| × 100 - 检查是否存在偏差超过3%的值
- 若存在,剔除相对偏差最大的那个值,重新计算均值
- 循环至所有剩余值的偏差均≤3%
代码实现
import pandas as pd import numpy as np # 1. 读取真实数据(替换为你的数据集路径) # sensor_data = pd.read_csv('your_sensor_data.csv', parse_dates=['timestamp']) # 构造模拟数据用于演示 timestamps = pd.date_range(start='2024-01-01 00:00:00', end='2024-01-01 01:00:00', freq='5T') sensor_data = pd.DataFrame({ 'timestamp': np.repeat(timestamps, 3), 'sensor_id': np.tile(['sensor_1', 'sensor_2', 'sensor_3'], len(timestamps)), 'temperature': np.random.normal(loc=25, scale=0.5, size=len(timestamps)*3) }) # 手动添加异常值测试 sensor_data.loc[[5, 12, 20], 'temperature'] = [30, 20, 28] # 2. 定义单窗口处理函数 def process_time_window(group): temps = group['temperature'].tolist() while True: current_mean = np.mean(temps) # 计算相对偏差 relative_deviations = [abs((temp - current_mean)/current_mean)*100 for temp in temps] # 检查是否全部符合要求 if all(dev <= 3 for dev in relative_deviations): break # 剔除偏差最大的数值 max_dev_idx = np.argmax(relative_deviations) temps.pop(max_dev_idx) # 返回自定义结果字段 return pd.Series({ 'timestamp': group['timestamp'].iloc[0], 'final_mean': round(np.mean(temps), 2), 'remaining_count': len(temps), 'remaining_temps': temps }) # 3. 按5分钟窗口分组处理 # 若原始时间不是整5分钟,改用pd.Grouper指定窗口:.groupby(pd.Grouper(key='timestamp', freq='5T')) processed_result = sensor_data.groupby('timestamp').apply(process_time_window).reset_index(drop=True) # 查看处理结果 print(processed_result.head())
关键细节说明
- 时间分组适配:如果原始数据的时间戳不是严格的5分钟整点数,使用
pd.Grouper(key='timestamp', freq='5T')替代直接按timestamp分组,确保同一5分钟窗口内的数据被归为一组。 - 动态均值计算:每次循环都基于当前剩余数据重新计算均值,完全匹配需求中“剔除后重新计算均值”的要求。
- 边界情况处理:当某组数据被剔除到只剩1个值时,循环自动终止(无其他值可产生偏差);若业务要求保留至少N个传感器数据,可在函数中添加
if len(temps) <= N: break的判断。 - 结果自定义:返回字段可根据需求调整,比如需要保留剩余传感器的ID,可在函数中同步跟踪传感器ID列表,而非仅保留温度值。
内容的提问来源于stack exchange,提问作者Normalitie
相关产品推荐
相关产品推荐

