Python中用前后行均值替换IMU数据3σ检测出的尖峰
解决IMU数据异常值替换为前后行均值的问题
问题背景
已通过3σ规则(适配性优于1.5IQR)识别出CSV格式IMU数据(含加速度计、陀螺仪、磁力计等)中偏离中位数3σ的尖峰,当前代码将异常值替换为中位数,需改为替换为异常值所在行前后相邻行的均值,且不删除尖峰、保留负值数据。
现有代码:
imu_var=['Accelerometer X','Accelerometer Y','Accelerometer Z','Gyroscope X','Gyroscope Y','Gyroscope Z','Magnetometer X','Magnetometer Y', 'Magnetometer Z','Pitch','Roll','Yaw','Temperature','Heave'] imu_sigma=imu[imu_var].std() imu_median=imu[imu_var].median() lower_imu = (imu_median - 3 * imu_sigma) upper_imu = (imu_median + 3 * imu_sigma) imu2=np.where((imu[imu_var] > upper_imu) | (imu[imu_var] < lower_imu),imu_median,imu[imu_var]) imu_out=pd.DataFrame(imu2,columns=imu_var) imu[imu_var]=imu_out[imu_var] imu_out.describe()
修改后的解决方案
核心思路是用shift()方法获取每行的前一行和后一行数据,计算均值后替换异常值:
import pandas as pd import numpy as np # 定义需要处理的IMU变量列 imu_var=['Accelerometer X','Accelerometer Y','Accelerometer Z','Gyroscope X','Gyroscope Y','Gyroscope Z','Magnetometer X','Magnetometer Y', 'Magnetometer Z','Pitch','Roll','Yaw','Temperature','Heave'] # 计算3σ阈值 imu_sigma = imu[imu_var].std() imu_median = imu[imu_var].median() lower_imu = imu_median - 3 * imu_sigma upper_imu = imu_median + 3 * imu_sigma # 生成前后行的均值数据:前一行(shift(1)) + 后一行(shift(-1)) 除以2 prev_row = imu[imu_var].shift(1) next_row = imu[imu_var].shift(-1) neighbor_mean = (prev_row + next_row) / 2 # 替换异常值:如果数据超出3σ范围,用前后行均值替换,否则保留原数据 imu_out = imu[imu_var].where(~((imu[imu_var] > upper_imu) | (imu[imu_var] < lower_imu)), neighbor_mean) # 将处理后的数据赋值回原DataFrame imu[imu_var] = imu_out # 查看处理后的数据统计信息 imu_out.describe()
关键说明
shift(1)获取当前行的前一行数据,shift(-1)获取后一行数据,两者取均值得到相邻行的平均值- 使用
where()方法:当条件不满足(即不是异常值)时保留原数据,条件满足时替换为相邻行均值 - 首行和末行的异常值:由于首行没有前一行、末行没有后一行,
shift()会生成NaN,可根据需求补充处理(比如用自身值、仅用单侧行值代替,或者保持NaN后再做填充)
内容的提问来源于stack exchange,提问作者Iwona
相关产品推荐
相关产品推荐

