Пользовательские функции скользящего временного окна Pandas с несколькими столбцами - PullRequest
0 голосов
/ 17 декабря 2018

У меня есть данные временных рядов в панде DataFrame, который выглядит следующим образом:

ts                         serial_number    device_tp       tp
2017-09-19T15:00:00.000Z    4ktpjlv     21.7760333333333    17
2017-09-19T14:00:00.000Z    4ktpjlv     19.8849833333333    16
2017-09-19T13:00:00.000Z    4ktpjlv     18.8565818181818    15
2017-09-19T12:00:00.000Z    4ktpjlv     18.7219666666667    13
2017-09-19T11:00:00.000Z    4ktpjlv     18.8341272727273    13
2017-09-19T10:00:00.000Z    4ktpjlv     18.9697833333333    14
2017-09-19T09:00:00.000Z    4ktpjlv     19.0422416666667    14

Я пытаюсь вычислить коэффициент корреляции Пирсона между tp и device_tp и применить алгоритм динамической деформации времени(используя fastdtw) для каждой информации, используя скользящее временное окно.Для каждого образца я оглядываюсь на последние 12 часов и вычисляю коэффициент корреляции и расстояние.

Я знаю, что панды как функция прокрутки, однако она возвращает не кадр данных, а ряд (илимассив ?).Проблема в том, что и коэффициенту корреляции, и fastdtw нужны два аргумента для работы: df.tp и df.device_tp.

Я нахожу другой способ, используя циклы, чтобы получить то, что я хочу:

for key, meas in df.iterrows(): 
   now = meas.ts
   start_date = now - pd.Timedelta(hours=12)
   new_df = df[(df['ts'] >= start_date) & (df['ts'] < now)]   
   if(new_df.shape[0] > 1):
       tp = df.tp.values
       device_tp = df.device_tp.values
       distance, _ = fastdtw(df['tp'], df['device_tp'])
       corr = stats.pearsonr(tp, device_tp)[0]
       # ... Predict flag here
       if(flag == 0):
           output = output.append(meas)

Но, конечно, это действительно не экономит время!Также мне интересно, что было бы лучшим способом сделать это?Я читал кое-что о переопределении функции прокрутки вместо использования встроенной функции pandas, но не могу понять, как это сделать.

Спасибо за помощь!

1 Ответ

0 голосов
/ 19 декабря 2018

Хорошо, поэтому эффективный способ получить оконную корреляцию - df["device_tp"].rolling(12, min_periods=2).corr(other=df["tp"]).

Я также не могу придумать прямой способ получить расстояние DTW.Одно из решений, которое дает мне примерно 8-кратное ускорение, - это пролонгировать pd.Series индексов и использовать полученные индексы с Rolling.apply:

from fastdtw import fastdtw 
def rolling_dtw(df, win=12, center=False, min_periods=2,
                col0="ts", col1="A", col2="B"):
    indices = df[col0]
    a = df[col1].values
    b = df[col2].values
    def rolldist(inds):  # calculate DTW for current indices
        inds = inds.astype(int)  # manual type-cast is needed here
        return fastdtw(a[inds], b[inds])[0]

    return indices.rolling(win, center=center,
                           min_periods=min_periods).apply(rolldist)

Но это решение также не слишком красиво.Предполагается, что расстояния между точками данных постоянны и составляют 1 час (для использования индексов).Вам необходимо настроить его, если это не так.

...