Python中如何利用Pandas计算平稳时间序列季节性分量的周期
方案1:完全匹配原有逻辑的无循环实现
如果你确认季节性分量是完全精确重复的,直接用向量化操作查找匹配位置即可,无需任何显式循环和条件判断:
import pandas as pd import numpy as np import matplotlib.pyplot as plt # 原有数据生成代码 seasonal = [-0.0012477419628991032, -0.0042654910887713745, -0.006234490214646844, 0.0007106773261453963, 1.1533604530851796e-08, -0.004141904258934777, 0.0006148978972421542, 0.0017480068715999646, 0.0011169491792932956, 0.002641724820318341, 0.005415250461344693, 0.003642109435703726, -0.0012477419628991032, -0.0042654910887713745, -0.006234490214646844, 0.0007106773261453963, 1.1533604530851796e-08, -0.004141904258934777, 0.0006148978972421542, 0.0017480068715999646, 0.0011169491792932956, 0.002641724820318341, 0.005415250461344693, 0.003642109435703726, -0.0012477419628991032, -0.0042654910887713745, -0.006234490214646844, 0.0007106773261453963, 1.1533604530851796e-08, -0.004141904258934777, 0.0006148978972421542, 0.0017480068715999646, 0.0011169491792932956, 0.002641724820318341, 0.005415250461344693, 0.003642109435703726, -0.0012477419628991032, -0.0042654910887713745, -0.006234490214646844, 0.0007106773261453963, 1.1533604530851796e-08, -0.004141904258934777, 0.0006148978972421542, 0.0017480068715999646, 0.0011169491792932956, 0.002641724820318341, 0.005415250461344693, 0.003642109435703726, -0.0012477419628991032, -0.0042654910887713745, -0.006234490214646844, 0.0007106773261453963, 1.1533604530851796e-08, -0.004141904258934777, 0.0006148978972421542, 0.0017480068715999646, 0.0011169491792932956, 0.002641724820318341, 0.005415250461344693, 0.003642109435703726, -0.0012477419628991032, -0.0042654910887713745, -0.006234490214646844, 0.0007106773261453963, 1.1533604530851796e-08, -0.004141904258934777, 0.0006148978972421542, 0.0017480068715999646, 0.0011169491792932956, 0.002641724820318341, 0.005415250461344693, 0.003642109435703726, -0.0012477419628991032, -0.0042654910887713745, -0.006234490214646844, 0.0007106773261453963, 1.1533604530851796e-08, -0.004141904258934777, 0.0006148978972421542, 0.0017480068715999646, 0.0011169491792932956, 0.002641724820318341, 0.005415250461344693, 0.003642109435703726, -0.0012477419628991032, -0.0042654910887713745, -0.006234490214646844, 0.0007106773261453963, 1.1533604530851796e-08, -0.004141904258934777, 0.0006148978972421542, 0.0017480068715999646, 0.0011169491792932956, 0.002641724820318341, 0.005415250461344693, 0.003642109435703726, -0.0012477419628991032, -0.0042654910887713745, -0.006234490214646844, 0.0007106773261453963, 1.1533604530851796e-08, -0.004141904258934777, 0.0006148978972421542, 0.0017480068715999646, 0.0011169491792932956, 0.002641724820318341, 0.005415250461344693, 0.003642109435703726, -0.0012477419628991032, -0.0042654910887713745, -0.006234490214646844, 0.0007106773261453963, 1.1533604530851796e-08, -0.004141904258934777, 0.0006148978972421542, 0.0017480068715999646, 0.0011169491792932956, 0.002641724820318341, 0.005415250461344693, 0.003642109435703726] indice = pd.date_range("2019-07-31 23:55:00", periods=len(seasonal), freq="T") seasonal = pd.Series(data=seasonal, index=indice) # 替换原有循环的核心代码 first_val = seasonal.iloc[0] match_positions = np.where(seasonal == first_val)[0] periodo = match_positions[1] - match_positions[0] print("Periodo: {}".format(periodo)) seasonal.plot() plt.show()
这个实现和你原有逻辑完全等价,输出结果也完全一致,所有操作都是向量化执行,性能比循环更高。
方案2:通用季节性周期检测(推荐)
实际生产环境中,序列分解得到的季节性分量往往存在微小的计算误差,不会完全精确重复,此时可以使用时间序列领域的标准方法:自相关系数(ACF)检测周期。自相关系数衡量序列当前值和滞后N阶的值的相关性,季节性周期对应的滞后阶数会出现明显的峰值:
from statsmodels.tsa.stattools import acf # 计算前24阶的自相关系数(可根据你预期的最大周期调整nlags参数) acf_values = acf(seasonal, nlags=24) # 跳过滞后0阶(自相关恒为1),取最大相关对应的滞后阶数即为周期 periodo = np.argmax(acf_values[1:]) + 1 print("Periodo: {}".format(periodo))
这个方法鲁棒性更强,就算后续数据有噪声、分量不是完全相等,也能正确识别出周期。
内容的提问来源于stack exchange,提问作者Johannes C.
相关产品推荐
相关产品推荐

