python - 如何在 Python 中对这 2 个循环进行向量化?

标签 python for-loop vectorization kalman-filter

我正在 values 中检索近 400k 个值,这本身就相当慢(该代码未显示),然后我尝试通过卡尔曼对这些值进行预测过滤器,第一个循环需要一分多钟的时间运行,第二个循环大约需要 2 分半钟,我认为第一个循环可以矢量化,但我不确定如何矢量化,特别是 window_sma 。第二个循环我不确定如何处理 i 增加 x 数组 (x = np.append(x, new_x_col, axis=1))。

这是第一个,它尝试使用 polyfit 和 polyval 根据 SMA 的值进行预测:

window_sma = 200
sma_index = 500
offset = 50
SMA = talib.SMA(values, timeperiod = window_sma)
vector_X = [1, 2, 3, 15]
sma_predicted = []

start_time = time.time()
for i in range (sma_index, len(SMA)):
    j = int(i - offset)
    k = int(i - offset / 2)
    window_sma = [SMA[j], SMA[k], SMA[i]]
    polyfit = np.polyfit([1, 2, 3], window_sma, 2)
    y_hat = np.polyval(polyfit, vector_X)
    sma_predicted.append(y_hat[-1])

第二个尝试过滤第一个 for 循环的输出,以便更好地预测我从 SMA 获得的值:

# Kalman Filter
km = KalmanFilter(dim_x = 2, dim_z = 1)

# state transition matrix
km.F = np.array([[1.,1.],
                [0.,1.]])
# Measurement function
km.H = np.array([[1.,0.]])

# Change in time
dt = 0.0001
a = 1.5

# Covariance Matrix
km.Q = np.power(a, 2) * \
       np.array([[np.power(dt,4)/4, np.power(dt,3)/2],
                 [np.power(dt,3)/2, np.power(dt,2)]])

# Variance
km.R = 1000

# Identity Matrix
I = np.array([[1, 0], [0, 1]])

# Measurement Matrix
km.Z = np.array(sma_predicted)

# Initial state
x = np.zeros((2,1))
x = np.array([[sma_predicted[0]], [0]])

# Initial distribution state's covariance matrix
km.P = np.array([[1000, 0], [0, 1000]])

for i in range (0, len(sma_predicted) - 1):
    # Prediction
    new_x_col = np.dot(km.F, x[:, i]).reshape(2, 1)
    x = np.append(x, new_x_col, axis=1)
    km.P = km.F * km.P * km.F.T + km.Q

    # Correction
    K = np.dot(km.P, km.H.T) / (np.dot(np.dot(km.H, km.P), km.H.T) + km.R)
    x[:, -1] = x[:, -1] + np.dot(K, (km.Z[i + 1] - np.dot(km.H, x[:, -1])))
    #x[:, -1] = (x[:, -1] + K * (km.Z[i + 1] - km.H * x[:, -1])).reshape(2, i + 2)
    km.P = (I - K * km.H) * km.P

谢谢!

最佳答案

第二个值得首先攻击,所以我就这样做。

你有这个:

x = np.array([[sma_predicted[0]], [0]])
for i in range (0, len(sma_predicted) - 1):
    new_x_col = np.dot(km.F, x[:, i]).reshape(2, 1)
    x = np.append(x, new_x_col, axis=1)
    # ...

在 NumPy 中重复附加到同一个数组总是不好的做法,所以从这样开始:

x = np.zeros((2, len(sma_predicted)))
x[0, 0] = sma_predicted[0]
for i in range(len(sma_predicted) - 1):
    x[:, i+1] = np.dot(km.F, x[:, i])
    # ...

注意 reshape(2, 1)由于 NumPy 广播,不需要。

我意识到这并不能回答您所有隐含的问题,但也许它可以让您开始。

如果 dot 那就太好了是 ufunc所以我们可以做类似 np.dot.outer(km.F, x.T) 的事情,但事实并非如此(参见 this from 2009 ),所以我们不能。您可以使用 Numba 实现更多加速(如我所示删除 append(),您的代码非常适合 Numba)。

关于python - 如何在 Python 中对这 2 个循环进行向量化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50302238/

相关文章:

r - 使用循环(或向量化)通过向量中的多个元素对列表进行子集化

matlab - 有上限和下限的cumsum?

python - Django - 无法导入应用程序名称 - Unresolved reference

C++:如何为 'for' 循环中的一行文本动态添加后缀以创建先前声明的变量

c++ - 错误 : expected primary-expression before '{' token

r - 如何在 R 中使用矢量化根据条件更改 DF 值?

python - 如何使用字典而不是大量 if/else 语句在 Python 中创建测验?

python - 创建一种编辑 .txt 文件的方法

python替代正则表达式搜索返回无的元组

java - 循环的简写是否缓存可迭代的引用?