如何将滚动卡尔曼滤波器应用于 DataFrame 中的列?

Posted

技术标签:

【中文标题】如何将滚动卡尔曼滤波器应用于 DataFrame 中的列?【英文标题】:How to apply a rolling Kalman Filter to a column in a DataFrame? 【发布时间】:2018-02-12 03:30:44 【问题描述】:

如何将滚动卡尔曼滤波器应用于 DataFrame 列(不使用外部数据)?

也就是说,假设每一行都是一个新的时间点,因此需要在每一行之后(以滚动方式)更新描述性统计信息。

例如,如何将卡尔曼滤波器应用于以下DataFrame中的任何列?

n = 2000
index = pd.date_range(start='2000-01-01', periods=n)
data = np.random.randn(n, 4)
df = pd.DataFrame(data, columns=list('ABCD'), index=index)

我已经看到了之前的回复(1 和 2),但是他们没有将其应用于 DataFrame 列(并且它们没有被矢量化)。

【问题讨论】:

你有没有想过如何做到这一点? 很遗憾没有 【参考方案1】:

利用numpy 的一些好的特性并使用pykalman 库,并在D 列上应用卡尔曼滤波器,滚动窗口为3,我们可以这样写:

import pandas as pd
from pykalman import KalmanFilter
import numpy as np

def rolling_window(a, step):
    shape   = a.shape[:-1] + (a.shape[-1] - step + 1, step)
    strides = a.strides + (a.strides[-1],)
    return np.lib.stride_tricks.as_strided(a, shape=shape, strides=strides)

def get_kf_value(y_values):
    kf = KalmanFilter()
    Kc, Ke = kf.em(y_values, n_iter=1).smooth(0)
    return Kc

n = 2000
index = pd.date_range(start='2000-01-01', periods=n)
data = np.random.randn(n, 4)
df = pd.DataFrame(data, columns=list('ABCD'), index=index)

wsize = 3
arr = rolling_window(df.D.values, wsize)
zero_padding = np.zeros(shape=(wsize-1,wsize))
arrst = np.concatenate((zero_padding, arr))
arrkalman = np.zeros(shape=(len(arrst),1))

for i in range(len(arrst)):
    arrkalman[i] = get_kf_value(arrst[i])

kalmandf = pd.DataFrame(arrkalman, columns=['D_kalman'], index=index)
df = pd.concat([df,kalmandf], axis=1)

df.head() 应该会产生这样的结果:

                   A         B         C         D  D_kalman
2000-01-01 -0.003156 -1.487031 -1.755621 -0.101233  0.000000
2000-01-02  0.172688 -0.767011 -0.965404 -0.131504  0.000000
2000-01-03 -0.025983 -0.388501 -0.904286  1.062163  0.013633
2000-01-04 -0.846606 -0.576383 -1.066489 -0.041979  0.068792
2000-01-05 -1.505048  0.498062  0.619800  0.012850  0.252550 

【讨论】:

谢谢!上面的示例如何从 3 个周期扩展到 10 个周期?尝试这样做但遇到了问题。 我编辑了示例以包含一个窗口大小变量wsize,所以如果你输入wsize = 10,你应该得到想要的结果@Greg。 有没有办法让卡尔曼滤波器“更强”,即更平滑?我可以设置哪些附加参数? pykalman 中有一个平滑参数,所有参数在他们的文档中都有解释:pykalman.github.io 另外另一种平滑的方法是使用更长的窗口大小。 @Nickpick

以上是关于如何将滚动卡尔曼滤波器应用于 DataFrame 中的列?的主要内容,如果未能解决你的问题,请参考以下文章

自动驾驶 9-6: EKF 的替代方案 - 无迹卡尔曼滤波器

自动驾驶 9-6: EKF 的替代方案 - 无迹卡尔曼滤波器

如何将 5Hz 的低通滤波器应用于 pandas 数据帧?

卡尔曼滤波

卡尔曼滤波实例——预测橘子的轨迹

扩展卡尔曼滤波器磁力计偏航漂移