Как я могу использовать Pandas, чтобы избежать циклов для оптимизации вероятностного взвешенного скользящего среднего (PWEMA)?Есть ли способ использовать EWM? - PullRequest
0 голосов
/ 11 июня 2019

Я пытаюсь оптимизировать функцию PWEMA для моих данных датчика в реальном времени для обнаружения аномалий в Pandas.В настоящее время он работает как цикл for с использованием iterrows (), но я хочу использовать функции Pandas для более быстрого вычисления для больших наборов данных, например, используя Apply () или векторизацию, или используя функцию EMA ...

PWEMA отличается от EMAиз-за параметра бета, который контролирует, насколько вы позволяете выбросам влиять на вашу MA, для стандартного EMA установлено значение 0.

import pandas as pd
import numpy as np
from datetime import datetime, timedelta
import datetime
import matplotlib.pyplot as plt
#plt.style.use('fivethirtyeight')
#%config InlineBackend.figure_format = 'retina'
#%matplotlib inline
from itertools import islice
from math import sqrt
from scipy.stats import norm


# generate random sensor data
ts = pd.date_range(start ='1-1-2019',  
         end ='1-10-2019', freq ='5T') 


np.random.seed(seed=1111)
data = np.random.normal(2.012547, 1.557331,size=len(ts))
df = pd.DataFrame({'timestamp': ts, 'speed': data})
df.speed = df.speed.abs()
df = df.set_index('timestamp')
time_col = 'timestamp'
value_col = 'speed'

#pewna parameters
T = 30      # number of points to consider in initial average
beta = 0.5  # parameter that controls how much you allow outliers to affect your MA, for standard EWMA set to 0EWMA
a = 0.99    # the maximum value of the EWMA a parameter, used for outliers
z = 3

#the PEWNA Model
#as described in Carter, Kevin M., and William W. Streilein. 

# create a DataFrame for the run time variables we'll need to calculate
pewm = pd.DataFrame(index=df.index, columns=['Mean', 'Var', 'Std'], dtype=float)
pewm.iloc[0] = [df.iloc[0][value_col], 0, 0]

t = 0

for _, row in islice(df.iterrows(), 1, None):
    diff = row[value_col] - pewm.iloc[t].Mean # difference from moving average
    p = norm.pdf(diff / pewm.iloc[t].Std) if pewm.iloc[t].Std != 0 else 0 # Prob of observing diff
    a_t = a * (1 - beta * p) if t > T else 1 - 1/(t+1) # weight to give to this point
    incr = (1 - a_t) * diff

    # Update Mean, Var, Std
    pewm.iloc[t+1].Mean = pewm.iloc[t].Mean + incr
    pewm.iloc[t+1].Var = a_t * (pewm.iloc[t].Var + diff * incr)
    pewm.iloc[t+1].Std = sqrt(pewm.iloc[t+1].Var)
    t += 1


The for loop currently takes too long to run on larger sets
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...