DataFrame异常值检测与移除:代码运行结果异常排查
问题解决:正确移除DataFrame异常行并生成可视化
问题分析
原代码存在以下核心错误:
- 错误的数据类型转换:将数值列的差值转成
Timedelta类型,完全偏离数值异常判断逻辑,导致异常识别彻底错误。 - 仅处理单一列:通过
orig_df.pop(columns[0])只提取第一列,其余列未做任何处理。 - 异常判断逻辑混乱:用时间差判断数值骤增,逻辑完全不匹配需求,最终导致误删正常行、保留异常值。
正确实现代码
import pandas as pd import matplotlib.pyplot as plt # 构造原始数据 data = { 'bucket': ['2023-01-01 00:05:00', '2023-01-01 00:06:00', '2023-01-01 00:07:00', '2023-01-01 00:08:00', '2023-01-01 00:09:00', '2023-01-01 00:10:00'], 'oph_single_positive_outlier': [1, 2, 3, 10, 4, 5], 'oph_single_negative_outlier': [1, 2, 3, 2, 4, 5], 'oph_1pos_1neg_outlier': [1, 10, 3, 2, 4, 5], 'oph_multipos_at_once_outlier': [1, 10, 10, 10, 4, 5] } orig_df = pd.DataFrame(data) orig_df['bucket'] = pd.to_datetime(orig_df['bucket']) orig_df.set_index('bucket', inplace=True) print("原始DataFrame:") display(orig_df) # 定义异常识别函数 def detect_outliers(series): # 计算相邻数值差值 diff = series.diff() # 下降行:当前值 < 前一个值(diff < 0) decreasing = diff < 0 # 骤增行:差值远大于正常增长幅度(这里正常增长为1,阈值设为2,即差值>2判定为骤增) rapid_increase = diff > 2 # 第一行没有前值,不判定 decreasing.iloc[0] = False rapid_increase.iloc[0] = False # 合并异常标记 return decreasing | rapid_increase # 遍历所有列,标记异常行 outlier_rows = pd.Series(False, index=orig_df.index) for col in orig_df.columns: col_outliers = detect_outliers(orig_df[col]) outlier_rows = outlier_rows | col_outliers # 移除异常行 cleaned_df = orig_df[~outlier_rows] print("\n清理后的DataFrame:") display(cleaned_df) # 输出被移除的异常行 print("\n被移除的异常行:") display(orig_df[outlier_rows]) # 生成每列的可视化图表 plt.figure(figsize=(15, 10)) for idx, col in enumerate(orig_df.columns, 1): plt.subplot(2, 2, idx) # 绘制原始数据折线 orig_df[col].plot(kind='line', marker='o', label='原始数据') # 标记异常点 orig_df[col][outlier_rows].plot(marker='x', color='red', markersize=12, label='异常值') # 绘制清理后的数据 cleaned_df[col].plot(kind='line', marker='s', color='green', label='清理后数据') plt.title(f'{col} 数据趋势与异常值') plt.xlabel('时间') plt.ylabel('数值') plt.legend() plt.grid(True) plt.tight_layout() plt.show()
代码说明
异常识别逻辑:
- 下降异常:当前数值小于前一个数值(
diff < 0) - 骤增异常:相邻数值差值超过设定阈值(这里根据示例设为2,可根据实际需求调整)
- 合并两种异常类型,标记所有需要删除的行
- 下降异常:当前数值小于前一个数值(
可视化部分:
- 对每列分别绘制折线图,包含原始数据、异常点(红色叉号)、清理后数据(绿色方块)
- 清晰展示异常值位置及清理后的数据趋势
运行结果说明
最终会移除以下两行:
2023-01-01 00:06:00:oph_1pos_1neg_outlier列骤增(1→10)2023-01-01 00:08:00:oph_single_positive_outlier骤增(3→10)、oph_single_negative_outlier下降(3→2)、oph_1pos_1neg_outlier下降(3→2)
完全符合需求中的异常行移除要求。
内容的提问来源于stack exchange,提问作者summerlove
相关产品推荐
相关产品推荐

