在Python中绘制具有平滑外观的时间序列的导数

在Python中绘制具有平滑外观的时间序列的导数,python,pandas,smoothing,kalman-filter,pykalman,Python,Pandas,Smoothing,Kalman Filter,Pykalman,我有一个很长的时间序列,像这样: 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

我有一个很长的时间序列,像这样:

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=导数。滚动(窗口=10,最小周期=3,中心=True,win\u type='boxcar')。平均值()
    获得:

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

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

    derivative.fillna(0,inplace=True)
    kf=Kalman滤波器(初始状态平均值=0)
    状态_表示,u=kf.filter(导数值)
    state_means=state_means.flatte()
    indexDate=衍生指数
    derivativeKalman=pd.系列(状态表示,指数表示指数)

要获得此信息:

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

如果你的目标是去除导数序列中的“异常值”峰值,我会尝试“滚动中值”首先,不是“滚动平均值”,因为中位数通常对异常值更不敏感

例如:

smotDeriv = derivative.rolling(window=10, min_periods=3, center=True).median()
然后,如果您想进一步平滑它,一个可能的选项是应用
rolling\u mean()

注意:因为我手头没有你的数据,所以我不确定
窗口
最小周期
的最佳值。这取决于你想平滑的程度。而且,在我看来,平滑导数越来越像是平滑原始时间序列,所以如果有一种已知的方法o平滑原始时间序列,这可能更直接


希望这有帮助。

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

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

假设函数的导数是处处定义的。当h非常小时,你会得到更好的导数近似值,当h非常大时,你会得到很差的导数近似值

在您的数据集中应用此方法存在一个问题。有时h可能会变得非常小,从而给出荒谬的高梯度值。有时h太大,以至于梯度估计非常糟糕。为了克服此问题,让我们定义时间t1和t2的两个阈值。如果连续时间差在t1和t2之间,则t当我们用这个点来确定梯度时,用上面的公式f’(x)。如果超过这个阈值,我们忽略这个点

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

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