在Python中用平滑的方式绘制一个时间序列的导数。

3

我有一个长的pandas时间序列,如下:

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

因为一些时间差(即分母)的值非常接近于零(有时甚至等于零),我在求导过程中得到了一些无穷大的值。实际上,我得到了这个:[]. [1]
时间序列蓝色(左刻度),导数绿色(右刻度)
现在我想平滑导数以使其更易读。我尝试了不同的操作,例如:
- 在较高的周期上计算差异: enter image description here
设置期数= 5,对于分子和分母
- 使用移动平均线: smotDeriv=derivative.rolling(window=10,min_periods=3,center=True,win_type='boxcar').mean() 得到:

enter image description here

我曾尝试使用不同的窗口类型,但没有任何有用的变化。
  • 我也考虑过剪切值,但我不知道使用哪些有效值作为最小和最大值。我尝试了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)

以达到这个目的:

enter image description here

实际上我找不到任何有用的改进。如果可能的话,你能给我建议如何提高图表上导数曲线的可读性吗?显然,我需要削减一些导数峰值,以获得一个平滑的曲线来近似真实值。我尝试了不同的窗口类型、周期等组合,但没有任何结果。关于卡尔曼滤波,我不是专家,可以说是新手,所以我只是按照this的默认值使用。我还发现了filterpy库,它实现了卡尔曼滤波,但我没有找到如何在不设置起始参数的情况下使用它。
2个回答

2
如果您的目标是在导数序列中去除“异常值”峰值,我建议首先尝试“滚动中位数”而不是“滚动平均”,因为中位数通常对异常值更不敏感。
例如:
smotDeriv = derivative.rolling(window=10, min_periods=3, center=True).median()

然后,如果你想进一步平滑它,其中一个可能的选择是应用rolling_mean()
注意:由于我手头没有你的数据来玩耍,我不确定windowmin_periods的最佳值。这取决于你想要平滑的程度。此外,对我来说,平滑导数更像是平滑原始时间序列,因此,如果有已知的方法可以平滑原始时间序列,那可能更加直观。
希望这可以帮助你。

0

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

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

假设您的函数的导数在任何地方都有定义。当 h 很小时,您将获得更好的导数近似值,而当 h 很大时,您将获得较差的导数近似值。

在处理数据集时,存在一个问题。有时 h 可以变得非常小,从而给出荒谬的梯度值。有时 h 太大,梯度估计值非常糟糕。为了解决这个问题,让我们定义两个时间阈值 t1 和 t2。如果连续的时间差在 t1 和 t2 之间,则使用上述 f'(x) 公式的点来确定梯度。如果超出此阈值,则忽略该点。

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

我们可以根据前一步找到的点拟合一个多项式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接