Более быстрая прокатка применяет стандартное отклонение и наклон на неравномерно распределенных временных рядах - PullRequest
1 голос
/ 30 апреля 2020

У меня есть Pandas (1.0. *) Фрейм данных, который содержит запись нескольких физических переменных (например, температуры, давления и влажности). Промежуток времени между двумя записями составляет примерно 1 с, но варьируется от 0,8 до 4 с.

Я хочу рассчитать стандартное отклонение и наклон (линейной регрессии) в 5-минутном скользящем окне.

Вот как я это делаю:

import numpy as np
import pandas as pd
import datetime
np.random.seed(1)

# Build the dummy dataset for testing
rows, cols = 1000, 3    
datetimes_sec = pd.date_range('2020-01-01', periods=rows, freq='1s').astype(np.int64) / 1e9
shifts = np.random.rand(rows) - 0.5  # Create random shift between -0.5s and +0.5s
datetimes = [sum(x) * 1e9 for x in zip(datetimes_sec, shifts)]    
df = pd.DataFrame(np.random.rand(rows,cols),
                  columns=['temperature', 'pressure', 'humidity'],
                  index=pd.to_datetime(datetimes))

# Custom function to calculate the slope
def get_slope(series):
    hours_since_epoch = series.index.astype(np.int64) / 3.6e12  # nanosecond to hour, I want the slope to be in [variable's unit] per hour
    slope = np.polyfit(hours_since_epoch, series, 1)[0]
    return slope

# Get the result
df = df.rolling("5min").agg(["std", get_slope]) 

Это работает, но слишком медленно: последняя строка занимает более 2 с для 1000 строк.

Я вижу, что мой Пользовательская функция get_slope отвечает, если я заменю ее стандартной функцией (например, min()), это займет 0,007 с. Но я могу найти способ сделать это быстрее.

Если невозможно получить тот же результат быстрее, обходным решением может быть пропуск некоторых строк данных: не прокручивать окно на каждой строке (т. Е. Для От 0,8 до 4 секунд), но производите вычисления только каждые 30 секунд:

  • вычисляйте sd и наклон всех (~ 300) данных в период с 00:00:00 до 00: 05: 00
  • рассчитать sd и наклон всех (~ 300) данных в период с 00:00:30 до 00: 05: 30
  • вычислить sd и наклон всех (~ 300) данных в период с 00:01:00 до 00: 06: 00
  • et c.

Вместо:

  • вычислить sd и наклон всех (~ 300) данных между 00:00 : 00 и 00: 05: 00
  • рассчитать sd и наклон всех (~ 300) данных в период с 00:00:01 до 00: 05: 01
  • вычислить sd и наклон всех ( ~ 300) данные между 00:00:02 и 00: 05: 02
  • и c.

Я не знаю, как это сделать (собственно pandas 'способ) с неравномерно расположенными данными.

Это ускорит процесс на 30, в обмен на потерю точности.

...