4. 识别并修正异常交易量

任务说明

本案例针对金融交易数据中交易量字段的异常值问题。实际业务中,交易量可能出现突然为零(数据缺失或系统故障)或数值极大(单位错误、重复计数)的情况。目标是对给定的一组交易记录,检测出交易量为零或超过合理阈值的记录,并采用前一日交易量的移动中位数进行修正,同时为每条异常记录添加标记字段,便于后续审计。

数据样例

以下为某股票连续10个交易日的交易量数据(单位:手),其中第4天为0,第8天为极大异常值:

日期,交易量
2024-01-01,15200
2024-01-02,14800
2024-01-03,16100
2024-01-04,0
2024-01-05,15500
2024-01-06,14900
2024-01-07,15800
2024-01-08,985000
2024-01-09,15300
2024-01-10,15100

实现代码


import pandas as pd
import numpy as np

def detect_and_fix_volume(data_path):
    """
    检测并修正交易量异常值
    规则:
    1. 交易量为0 → 异常
    2. 交易量 > 前5日滚动中位数 * 3 → 异常
    修正:用前5日滚动中位数替换异常值
    """
    df = pd.read_csv(data_path)
    
    # 计算前5日滚动中位数(shift保证只用历史数据)
    df['rolling_med'] = df['交易量'].rolling(window=5, min_periods=1).median().shift(1)
    
    # 异常判定
    df['is_anomaly'] = False
    df.loc[df['交易量'] == 0, 'is_anomaly'] = True
    df.loc[df['交易量'] > df['rolling_med'] * 3, 'is_anomaly'] = True
    
    # 修正:用滚动中位数替换异常值
    df['修正后交易量'] = df['交易量'].copy()
    df.loc[df['is_anomaly'], '修正后交易量'] = df.loc[df['is_anomaly'], 'rolling_med']
    
    # 输出结果
    result = df[['日期', '交易量', '修正后交易量', 'is_anomaly']].copy()
    result['is_anomaly'] = result['is_anomaly'].map({True: '是', False: '否'})
    return result

# 执行检测
if __name__ == "__main__":
    # 将上述数据保存为 volume_data.csv 后运行
    result_df = detect_and_fix_volume('volume_data.csv')
    print(result_df.to_string(index=False))

执行方式

将数据样例保存为volume_data.csv(包含表头),与上述Python代码置于同一目录。运行python volume_check.py(假设代码保存为该文件名),需确保已安装pandas和numpy库。

验证方法与判定标准

运行后观察输出结果,满足以下条件即判定通过:

  • 第4行(2024-01-04)交易量为0,is_anomaly列为“是”,修正后交易量等于前5日(含当日)滚动中位数(即15200、14800、16100的中位数15200);
  • 第8行(2024-01-08)交易量为985000,超过前5日滚动中位数(15500)的3倍(46500),is_anomaly列为“是”,修正后交易量等于15500;
  • 其余行is_anomaly均为“否”,修正后交易量与原交易量一致。

预期输出


日期        交易量  修正后交易量  is_anomaly
2024-01-01  15200    15200.0          否
2024-01-02  14800    14800.0          否
2024-01-03  16100    16100.0          否
2024-01-04      0    15200.0          是
2024-01-05  15500    15500.0          否
2024-01-06  14900    14900.0          否
2024-01-07  15800    15800.0          否
2024-01-08 985000    15500.0          是
2024-01-09  15300    15300.0          否
2024-01-10  15100    15100.0          否
交易量异常检测与修正流程 原始交易数据 日期 + 交易量 步骤1: 滚动中位数 window=5, shift(1) 仅用历史数据 步骤2: 异常判定 条件1: 交易量 == 0 条件2: 交易量 > 中位数×3 是否异常? is_anomaly 否 保留原值 修正后 = 原交易量 是 修正为滚动中位数 修正后 = rolling_med 输出: 修正后数据 + 异常标记 日期 | 原值 | 修正值 | is_anomaly