1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns from scipy.stats.mstats import winsorize #指定图像样式 plt.style.use('seaborn-v0_8') #指定字体,防止中文出现乱码,windows系统指定为‘SimHei’ plt.rcParams['font.sans-serif'] = ['SimHei'] #这行代码让中文的负号“-”可以正常显示 plt.rcParams["axes.unicode_minus"]=False
# 1. 创建示例数据(含异常值,替换为你的实际数据) df = pd.read_excel('../数据/2-1.xlsx') df = df[['日期', '收盘']] df['日期'] = pd.to_datetime(df['日期']) df.set_index('日期', inplace = True)
# 2. 温索化处理(双侧1%截断) df['温索化处理价'] = winsorize(df['收盘'], limits=[0.01, 0.01])
# 3. 标记原始异常值 q1 = df['收盘'].quantile(0.01) q99 = df['收盘'].quantile(0.99) df['异常值标记'] = (df['收盘'] < q1) | (df['收盘'] > q99)
# 4. 可视化对比 plt.figure(figsize=(14, 10), dpi=100)
# 4.1 原始收盘价与温索化对比 plt.subplot(2, 1, 1) plt.plot(df.index, df['收盘'], label='原始收盘价', color='blue', alpha=0.7) plt.plot(df.index, df['温索化处理价'], label='温索化处理价', color='red', linewidth=2) plt.scatter(df.index[df['异常值标记']], df.loc[df['异常值标记'], '收盘'], color='red', s=80, label='异常值点') plt.fill_between(df.index, q1, q99, color='gray', alpha=0.2, label='正常波动区间') plt.title('收盘价温索化处理效果对比', fontsize=16) plt.ylabel('价格', fontsize=12) plt.legend(loc='upper left') plt.grid(alpha=0.3)
# 4.2 箱线图对比 plt.subplot(2, 1, 2) plt.boxplot([df['收盘'], df['温索化处理价']], labels=['原始收盘价', '温索化处理价'], patch_artist=True, boxprops=dict(facecolor='lightblue')) plt.title('箱线图对比', fontsize=16) plt.ylabel('价格分布', fontsize=12) plt.grid(alpha=0.3)
plt.tight_layout() plt.show()
# 5. 统计结果分析 print(f"原始数据异常值数量: {df['异常值标记'].sum()}") print(f"温索化处理范围: {q1:.2f} ~ {q99:.2f}") print("异常值处理详情:") print(df.loc[df['异常值标记'], ['收盘', '温索化处理价']])
|