Как эти 2 цикла можно векторизовать в Python? - PullRequest
0 голосов
/ 12 мая 2018

Я получаю около 400 тыс. Значений в values, что само по себе довольно медленно (этот код не отображается), а затем я пытаюсь сделать прогноз этих значений через фильтр Кальмана, первый циклНа запуск уходит чуть более минуты, а второй - на 2 с половиной минуты, я думаю, что первый можно векторизовать, но я не уверен, каким образом, особенно window_sma.Второй цикл Я не уверен, как я мог справиться с увеличением i массива x (x = np.append(x, new_x_col, axis=1)).

Это первый цикл, который пытается сделать прогноз на основе значений из SMA,используя polyfit и polyval:

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

Спасибо!

1 Ответ

0 голосов
/ 12 мая 2018

Второй стоит атаковать первым, поэтому я просто сделаю это.

У вас есть это:

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), но это не так (см. это из 2009 ), поэтому мы не можем.Вы могли бы реализовать больше ускорений, используя Numba (с удаленным append(), как я показал, ваш код является хорошим кандидатом для Numba).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...