Как удалить выбросы, указанные c для каждой временной метки? - PullRequest
1 голос
/ 17 июня 2020

У меня есть приведенный ниже фрейм данных, который представляет собой данные временного ряда, и я обрабатываю эту информацию для ввода в мои модели прогнозирования.

df = pd.DataFrame({"timestamp": [pd.Timestamp('2019-01-01 01:00:00', tz=None),
                               pd.Timestamp('2019-01-01 01:00:00', tz=None),
                               pd.Timestamp('2019-01-01 01:00:00', tz=None),
                               pd.Timestamp('2019-01-01 02:00:00', tz=None),
                               pd.Timestamp('2019-01-01 02:00:00', tz=None),
                               pd.Timestamp('2019-01-01 02:00:00', tz=None),
                               pd.Timestamp('2019-01-01 03:00:00', tz=None),
                               pd.Timestamp('2019-01-01 03:00:00', tz=None),
                               pd.Timestamp('2019-01-01 03:00:00', tz=None)],
                   "value":[5.4,5.1,100.8,20.12,21.5,80.08,150.09,160.12,20.06]

                  })

Отсюда я беру среднее значение для каждой временной метки и отправляю это значение в качестве входных данных для предсказателя. Но в настоящее время я использую только пороговые значения для фильтрации выбросов, но они, похоже, отфильтровывают реальные значения, а также не фильтруют некоторые выбросы.

Например, я оставил

df[(df['value']>3 )& (df['value']<120 )]

и тогда это не отфильтровывает

2019-01-01 01:00:00 100.8

, которое является выбросом для этой временной метки, и отфильтровывает

2019-01-01 03:00:00 150.09
2019-01-01 03:00:00 160.12

, которые не являются выбросами для этой временной метки.

Итак, как мне отфильтровать выбросы для каждой временной метки на основе того, какая из них не подходит для этой группы?

Любая помощь приветствуется.

1 Ответ

1 голос
/ 18 июня 2020

Хорошо, предположим, вы ищете доверительный интервал для обнаружения выбросов.

Затем вам нужно получить среднее значение и доверительные интервалы для каждой группы временных меток. Поэтому вы можете запустить :

stats = df.groupby(['timestamp'])['value'].agg(['mean', 'count', 'std'])
ci95_hi = []
ci95_lo = []
import math
for i in stats.index:
    m, c, s = stats.loc[i]
    ci95_hi.append(m + 1.96*s/math.sqrt(c))
    ci95_lo.append(m - 1.96*s/math.sqrt(c))

stats['ci95_hi'] = ci95_hi
stats['ci95_lo'] = ci95_lo
df = pd.merge(df, stats, how='left', on='timestamp')

, что приведет к следующему выводу: enter image description here

, тогда вы можете настроить столбец фильтра:

import numpy as np
df['Outlier'] = np.where(df['value'] >= df['ci95_hi'], 1, np.where(df['value']<= df['ci95_lo'], 1, 0))

то все, что имеет значение 1 в столбце выброса, является выбросом. Вы можете настроить значения с помощью 1,96, чтобы немного поиграть с ним.

Результат выглядит так: enter image description here

...