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 否