提示词
1
| 有一个DataFrame,包含日期和股票的收益价,请用Pelt算法对其进行变点检测。
|
答案
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 60
| import pandas as pd import numpy as np import matplotlib.pyplot as plt import ruptures as rpt
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.columns = ['date','Close'] df['date'] = pd.to_datetime(df['date']) df.set_index('date', inplace = True)
# 2. 数据预处理 signal = df['Close'].values # 提取收盘价信号
# 3. PELT变点检测配置 model = "rbf" # 检测均值和方差变化[8](@ref) algo = rpt.Pelt(model=model).fit(signal) penalty = 3 * np.log(len(signal)) # 动态惩罚系数 change_points = algo.predict(pen=penalty)
# 4. 可视化结果 plt.figure(figsize=(14, 7)) plt.plot(df.index, df['Close'], label='收盘价', lw=1.5)
# 标记变点(排除最后一个索引) for cp in change_points[:-1]: plt.axvline(x=df.index[cp], color='red', ls='--', alpha=0.7, label='变点' if cp == change_points[0] else None)
# 添加分段着色 prev_cp = 0 colors = ['#E6F3FF', '#FFE9E6', '#F0F0FF'] for i, cp in enumerate(change_points[:-1]): plt.axvspan(df.index[prev_cp], df.index[cp], facecolor=colors[i%3], alpha=0.3) prev_cp = cp
plt.title('股票收盘价变点检测 (PELT算法)', fontsize=14) plt.ylabel('价格', fontsize=12) plt.grid(alpha=0.3) plt.legend() plt.tight_layout() plt.show()
# 5. 输出变点信息 print(f"检测到变点数量: {len(change_points)-1}") print("变点日期及价格详情:") cp_df = pd.DataFrame({ '变点日期': df.index[change_points[:-1]], '收盘价': df['Close'].iloc[change_points[:-1]].values, '窗口长度': np.diff([0]+change_points[:-1]) # 各段长度 }) print(cp_df)
|
数据导入以及防止画图中文乱码的代码是我加进去的,其余都是ai写的。
图像:
