我有一个像这样的长熊猫时间序列:
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时间的某些值(以denominat为单位)非常接近(或有时相等)为零,所以我的导数中得到了一些inf值。实际上我得到了这个:[
时间序列蓝色(左侧刻度),衍生绿色(右侧刻度)
现在我想平滑衍生物以使其更具可读性。我尝试了不同的操作,例如:
为numer和denominat设置句点= 5
smotDeriv=derivative.rolling(window=10,min_periods=3,center=True,win_type='boxcar').mean()
获取:我还使用了不同的窗口类型而没有任何有用的更改
我还使用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库,但是我没有找到如何在不设置启动参数的情况下使用它。
答案 0 :(得分:1)
如果您的目标是消除衍生系列中的“异常值”峰值,我会首先尝试“滚动中位数”而不是“滚动均值”,因为中位数通常对异常值更不敏感。
例如:
smotDeriv = derivative.rolling(window=10, min_periods=3, center=True).median()
然后,如果您想进一步解决这个问题,可能的选择之一就是应用rolling_mean()
。
注意:由于我手边没有您的数据,我不确定window
和min_periods
的最佳值。这取决于你想要平滑多远。此外,在我看来,平滑导数变得更像平滑原始时间序列,所以如果有一种已知的方法来平滑原始时间序列,那可能更直接。
希望这有帮助。
答案 1 :(得分:0)
我们知道函数的派生定义如下:
f'(x)= lim_(h - > 0)(f(x + h) - f(x - h))/ 2h
让我们假设你的函数的导数是在每个地方定义的。当h非常小时,你会得到一个更好的导数近似值,当h非常大时,你会得到一个很差的导数近似值。
在数据集的情况下应用此方法存在问题。有时h可能变得非常小,基本上给出了非常高的梯度值。有时h太大,梯度估计非常糟糕。为了克服这个问题,我们定义两个时间阈值t1和t2。如果连续时间差在t1和t2之间,那么我们使用该点通过上述f'(x)公式确定梯度。如果超出此阈值,我们会忽略这一点。
我们如何计算其余点的渐变?
我们可以根据我们在上一步中找到的点拟合多项式。