如何在列表内执行数学运算实现时间序列滑动平滑?
在Jupyter Notebook中实现指定公式的时间序列滑动平滑
1. 数据准备与导入
首先将你的原始时间序列数据转换为可处理的格式,用Pandas加载并处理缺失值(原始数据中空的月份用NaN标记):
import pandas as pd import numpy as np # 整理原始数据,空月份替换为NaN raw_data = [ [1960, 5], [1961,7], [1961,8], [1961,11], [1962,5], [1963,6], [1964, np.nan], [1965,7], [1966,7], [1966,7], [1966,10], [1967,4], [1967,8], [1968, np.nan], [1969, np.nan], [1970,8], [1971,6], [1971,9], [1971,10], [1972,7], [1973,6], [1973,9], [1974,10], [1974,10], [1975,10], [1976, np.nan], [1977, np.nan], [1978,9], [1979,11], [1980,7], [1980,7], [1980,8], [1981, np.nan], [1982,10], [1982,12], [1983, np.nan], [1984,7], [1985,9], [1986, np.nan], [1987, np.nan], [1988,9], [1988,10], [1989,7], [1989,10], [1990, np.nan], [1991,7], [1992, np.nan], [1993,6], [1993,7], [1993,9], [1993,9], [1994, np.nan], [1995,7], [1996,8], [1996,9], [1997,5], [1998,8], [1998,9], [1998,10], [1999,8], [1999,9], [2000,9], [2001, np.nan], [2002,1], [2003,5], [2003,7], [2003,8], [2003,9], [2003,10], [2004, np.nan], [2005,11], [2006,7], [2006,10], [2007,9], [2007,11], [2007,11], [2008,5], [2009,5], [2009,7], [2009,9], [2009,9], [2010,10], [2011,5], [2011,9], [2011,9], [2012,8], [2013,7], [2014,9], [2015,7], [2016, np.nan], [2017,8], [2018,10], [2019,11], [2020, np.nan] ] # 转换为DataFrame df = pd.DataFrame(raw_data, columns=['YEAR', 'MONTH'])
2. 缺失值处理(必选步骤)
你的公式需要5个连续的窗口值,空值会导致计算失败。推荐用线性插值填充缺失的月份值:
# 线性插值填充空值 df['MONTH'] = df['MONTH'].interpolate(method='linear')
如果不需要插值,也可以选择跳过含空值的窗口,但会丢失部分数据,根据需求调整。
3. 实现滑动平滑公式
你的公式((A-E)+3*(B+D)+4*C)/12是5点加权滑动窗口,对应序列中每个位置的:
- A:当前点前2位的值
- B:当前点前1位的值
- C:当前点的值
- D:当前点后1位的值
- E:当前点后2位的值
高效实现方式(无循环)
用Pandas的移位操作实现,适合大数据量:
# 生成各位置的移位值 df['A'] = df['MONTH'].shift(2) # 前2位 df['B'] = df['MONTH'].shift(1) # 前1位 df['D'] = df['MONTH'].shift(-1) # 后1位 df['E'] = df['MONTH'].shift(-2) # 后2位 # 计算平滑值 df['SMOOTHED_MONTH'] = ((df['A'] - df['E']) + 3*(df['B'] + df['D']) + 4*df['MONTH']) / 12 # 删除临时移位列 df.drop(['A', 'B', 'D', 'E'], axis=1, inplace=True)
直观循环实现(适合理解逻辑)
如果需要更直观的逻辑展示,用循环遍历每个可计算的位置:
df['SMOOTHED_MONTH'] = np.nan # 遍历所有有完整窗口的位置(跳过前2个和后2个点) for i in range(2, len(df)-2): A = df['MONTH'].iloc[i-2] B = df['MONTH'].iloc[i-1] C = df['MONTH'].iloc[i] D = df['MONTH'].iloc[i+1] E = df['MONTH'].iloc[i+2] df['SMOOTHED_MONTH'].iloc[i] = ((A - E) + 3*(B + D) + 4*C) / 12
4. 查看结果
运行代码后,SMOOTHED_MONTH列即为平滑后的序列。前2行和最后2行因缺少窗口数据会保留NaN,可根据需求用前后值填充或直接忽略:
# 打印结果示例 print(df[['YEAR', 'MONTH', 'SMOOTHED_MONTH']].head(10))
内容的提问来源于stack exchange,提问作者user2543
相关产品推荐
相关产品推荐

