【问题标题】:Python Pandas Moving Average LagPython Pandas 移动平均滞后
【发布时间】:2017-08-26 08:05:51
【问题描述】:

考虑以下 Python 程序:

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

data = [["2017-05-25 22:00:00", 5],
["2017-05-25 22:05:00", 7],
["2017-05-25 22:10:00", 9],
["2017-05-25 22:15:00", 10],
["2017-05-25 22:20:00", 15],
["2017-05-25 22:25:00", 20],
["2017-05-25 22:30:00", 25],
["2017-05-25 22:35:00", 32]]

df = pd.DataFrame(data)
df.columns = ["date", "value"]
df["date2"] = pd.to_datetime(df["date"],format="%Y-%m-%d %H:%M:%S")

ts = pd.Series(df["value"].values, index=df["date2"])
mean_smoothed = ts.rolling(window=5).mean()
exp_smoothed = ts.ewm(alpha=0.5).mean()

h1 = ts.head(8)
h2 = mean_smoothed.head(8)
h3 = exp_smoothed.head(8)
k = pd.concat([h1, h2, h3], join='outer', axis=1)
k.columns = ["Actual", "Moving Average", "Exp Smoothing"]
print(k)

打印出来

                     Actual  Moving Average  Exp Smoothing
date2                                                     
2017-05-25 22:00:00       5             NaN       5.000000
2017-05-25 22:05:00       7             NaN       6.333333
2017-05-25 22:10:00       9             NaN       7.857143
2017-05-25 22:15:00      10             NaN       9.000000
2017-05-25 22:20:00      15             9.2      12.096774
2017-05-25 22:25:00      20            12.2      16.111111
2017-05-25 22:30:00      25            15.8      20.590551
2017-05-25 22:35:00      32            20.4      26.317647

画图

plt.figure(figsize=(16,5))
plt.plot(ts, label="Original")
plt.plot(mean_smoothed, label="Moving Average")
plt.plot(exp_smoothed, label="Exponentially Weighted Average")
plt.legend()
plt.show()

移动平均 (MA) 和指数平滑 (ES) 都会引入滞后:在上面的示例 MA 中,需要 5 个值来预测第 6 个值是什么。但是,如果查看表格,MA 列中只有 4 个 NaN 值,第 5 个值已经是非 NaN 值(=第一个预测)。

问题:如何在图表中绘制这些值以正确保留滞后?看 ES,其实更明显一点:ES 应该从 t=2 开始,但是开始却立即开始。

【问题讨论】:

  • 您似乎收到了两个答案,可以根据您的喜好解决您的问题。如果任何建议的解决方案对您有用,请考虑查看this

标签: python pandas signal-processing


【解决方案1】:

您似乎误解了移动平均线。对于 MA(5),它需要 5 个数据点来计算。获得第 5 点后,可以使用点 1-5 计算第 5 点的平均值。因此,您应该只有 4 个 NaN。

如果你想转移你的数据,你可以试试:

df.shift(n) # n is an integer

要么将实际值移位 -1,要么将所有值移位 1。

Here 是它的文档。

【讨论】:

    【解决方案2】:

    插值应该可以解决问题。

    import pandas as pd
    import seaborn as sns
    import matplotlib.pyplot as plt
    
    data = [["2017-05-25 22:00:00", 5],
    ["2017-05-25 22:05:00", 7],
    ["2017-05-25 22:10:00", 9],
    ["2017-05-25 22:15:00", 10],
    ["2017-05-25 22:20:00", 15],
    ["2017-05-25 22:25:00", 20],
    ["2017-05-25 22:30:00", 25],
    ["2017-05-25 22:35:00", 32]]
    
    df = pd.DataFrame(data)
    df.columns = ["date", "value"]
    df["date2"] = pd.to_datetime(df["date"],format="%Y-%m-%d %H:%M:%S")
    
    ts = pd.Series(df["value"].values, index=df["date2"])
    mean_smoothed = ts.rolling(window=5).mean()
    ###### NEW #########
    mean_smoothed[0]=ts[0]
    mean_smoothed.interpolate(inplace=True)
    ####################
    exp_smoothed = ts.ewm(alpha=0.5).mean()
    
    h1 = ts.head(8)
    h2 = mean_smoothed.head(8)
    h3 = exp_smoothed.head(8)
    k = pd.concat([h1, h2, h3], join='outer', axis=1)
    k.columns = ["Actual", "Moving Average", "Exp Smoothing"]
    print(k)
    
    
    plt.figure(figsize=(16,5))
    plt.plot(ts, label="Original")
    plt.plot(mean_smoothed, label="Moving Average")
    plt.plot(exp_smoothed, label="Exponentially Weighted Average")
    plt.legend()
    plt.show()
    

    【讨论】:

      猜你喜欢
      • 2012-11-19
      • 1970-01-01
      • 2021-08-13
      • 2018-05-08
      • 2019-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-30
      相关资源
      最近更新 更多