在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值。实际上我得到了这个:[
时间序列蓝色(左刻度),导数绿色(右刻度)
现在我想对导数进行平滑处理,使其更具可读性。我尝试了不同的操作,如:
- 计算较高期间的差异:
- 使用移动平均线:
获得: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.系列(状态表示,指数表示指数)
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)。如果超过这个阈值,我们忽略这个点 我们如何计算其余点的梯度 我们可以根据上一步找到的点拟合多项式