【问题标题】:Plot a derivative of a time series with a smoothed look in Python在 Python 中绘制具有平滑外观的时间序列的导数
【发布时间】:2018-11-18 20:01:59
【问题描述】:

我有一个像这样的长熊猫时间序列:

2017-11-27 16:19:00     120.0
2017-11-30 02:40:35     373.4
2017-11-30 02:40:42     624.5
2017-12-01 14:15:31     871.8
2017-12-01 14:15:33    1120.0
2017-12-07 21:07:04    1372.2
2017-12-08 06:11:50    1660.0
2017-12-08 06:11:53    1946.7
2017-12-08 06:11:57    2235.3
2017-12-08 06:12:00    2521.3
....
dtype: float64

我想把它和它的导数一起绘制。根据定义,我以这种方式计算导数:

numer=myTimeSeries.diff()
denominat=myTimeSeries.index.to_series().diff().dt.total_seconds()/3600
derivative=numer/denominat

因为 delta time 的某些值(即以面值表示)非常接近(或有时等于)零,所以我在导数中得到了一些 inf 值。实际上我得到了这个:[

时间序列蓝色(左刻度),导数绿色(右刻度)

现在我想平滑导数以使其更具可读性。我尝试了不同的操作,例如:

  • 计算较高时期的差异:

为数字和面额设置句点=5

  • 使用移动平均线:smotDeriv=derivative.rolling(window=10,min_periods=3,center=True,win_type='boxcar').mean() 获取:

我也使用了不同的窗口类型,没有任何有用的改变

  • 我也想剪裁这些值,但我不知道将哪些有效值用作最小值和最大值。我尝试了 25% 和 75% 的分位数,但没有任何优势
  • 我还绑定了使用 pykalman 的卡尔曼滤波器:

    derivative.fillna(0,inplace=True) kf = KalmanFilter(initial_state_mean=0) state_means,_ = kf.filter(derivative.values) state_means = state_means.flatten() indexDate=derivative.index derivativeKalman=pd.Series(state_means,index=indexDate)

得到这个:

实际上我找不到任何有用的改进。如果可能的话,你能建议我如何提高图表上导数图的可读性。显然,我会削减导数的一些峰值以获得接近真实值的平滑曲线。我尝试了关于窗口类型、周期等的不同组合。没有任何结果。关于卡尔曼滤波器,我不是专家,假设是新手,所以我只是使用this 之后的默认值。我还找到了实现卡尔曼滤波器的 filterpy 库,但我还没有找到如何在不设置启动参数的情况下使用它。

【问题讨论】:

    标签: python pandas smoothing kalman-filter pykalman


    【解决方案1】:

    如果您的目标是消除导数系列中的“异常值”峰值,我会先尝试“滚动中值”而不是“滚动平均值”,因为中值通常对异常值更不敏感。

    例如:

    smotDeriv = derivative.rolling(window=10, min_periods=3, center=True).median()
    

    然后,如果您想进一步平滑它,可能的选项之一是应用rolling_mean()

    注意:由于我手头没有您的数据可玩,我不确定windowmin_periods 的最佳值。这取决于您想要平滑它的程度。此外,在我看来,平滑导数变得更像是平滑原始时间序列,所以如果有一种已知的方法可以平滑原始时间序列,那可能会更直接。

    希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      我们知道函数的导数定义如下:

      f'(x) = lim_(h -> 0) (f(x + h) - f(x - h)) / 2h

      让我们假设你的函数的导数在每个地方都定义了。当 h 非常小时,您将获得更好的导数近似值,当 h 非常大时,您将获得差的导数近似值。

      在您的数据集的情况下应用此方法存在问题。有时 h 可能会变得非常小,从而基本上给出高得离谱的梯度值。有时 h 太大以至于梯度估计非常糟糕。为了克服这个问题,让我们定义两个时间阈值 t1 和 t2。如果连续的时间差在 t1 和 t2 之间,那么我们使用该点通过上面的 f'(x) 公式确定梯度。如果超过这个阈值,我们忽略这一点。

      我们如何计算其余点的梯度?

      我们可以根据在上一步中找到的点来拟合多项式。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-08
        • 1970-01-01
        • 2013-06-13
        • 2019-05-12
        • 1970-01-01
        • 1970-01-01
        • 2020-07-12
        • 2018-01-24
        相关资源
        最近更新 更多