如何用Python Pandas过滤数据中的异常值?现有方法仅实现平滑
异常点剔除解决方案
savgol_filter是平滑滤波工具,只能消除高频噪声,没法直接剔除偏离正常范围的孤立异常点。下面给你几个实用的剔除方案,按需选择:
1. 单维度统计筛选:四分位距(IQR)法
适合单个坐标(比如z轴)存在明显异常值的场景,用统计范围圈定正常数据:
import pandas as pd import matplotlib.pyplot as plt # 假设数据存在df中,列名是'x'和'z' # 计算z列的四分位数与IQR范围 q1 = df['z'].quantile(0.25) q3 = df['z'].quantile(0.75) iqr = q3 - q1 # 定义正常数据的上下边界(超出这个范围的就是异常点) lower_limit = q1 - 1.5 * iqr upper_limit = q3 + 1.5 * iqr # 筛选出正常数据 filtered_df = df[(df['z'] >= lower_limit) & (df['z'] <= upper_limit)] # 对比可视化 plt.scatter(df['x'], df['z'], label='原始数据', alpha=0.5) plt.scatter(filtered_df['x'], filtered_df['z'], label='剔除异常后', c='red') plt.legend() plt.show()
2. 单维度统计筛选:Z-score法
基于数据的均值和标准差,把偏离3倍标准差的点判定为异常(阈值可调整):
from scipy.stats import zscore import pandas as pd import matplotlib.pyplot as plt # 计算z列的Z-score df['z_score'] = zscore(df['z']) # 保留Z-score绝对值小于3的正常点 filtered_df = df[abs(df['z_score']) < 3] # 绘图对比 plt.scatter(df['x'], df['z'], label='原始数据', alpha=0.5) plt.scatter(filtered_df['x'], filtered_df['z'], label='剔除异常后', c='red') plt.legend() plt.show()
3. 二维空间聚类:DBSCAN法
适合x-z坐标联合出现的孤立异常点,能识别空间上离群的孤立点:
from sklearn.cluster import DBSCAN import pandas as pd import matplotlib.pyplot as plt # 提取x、z的特征矩阵 coords = df[['x', 'z']].values # 初始化DBSCAN,eps是邻域半径,min_samples是邻域内最少点数,需根据数据尺度调整 dbscan = DBSCAN(eps=0.5, min_samples=5) cluster_labels = dbscan.fit_predict(coords) # 标签为-1的是异常点,筛选正常点 filtered_df = df[cluster_labels != -1] # 可视化展示 plt.scatter(df['x'], df['z'], c=cluster_labels, cmap='viridis', alpha=0.5, label='原始数据') plt.scatter(filtered_df['x'], filtered_df['z'], c='red', label='剔除异常后') plt.legend() plt.show()
注意事项
- 如果异常点出现在x轴,把代码里的
z换成x即可 - DBSCAN的
eps和min_samples要根据你的数据实际分布调整,比如先看数据的坐标范围再设参数 - 统计方法适合单维度异常,空间聚类适合二维联合的异常场景
内容的提问来源于stack exchange,提问作者tulips
相关产品推荐
相关产品推荐

