Есть ли альтернатива stats.zscore для обнаружения выбросов в кадре данных с менее чем 10 строками? - PullRequest
1 голос
/ 17 июня 2020

Я пытаюсь найти способ применить алгоритм, предназначенный для работы с большими фреймами данных, к очень маленькому фрейму данных, так как идея состоит в том, чтобы получать каждую строку данных динамически от беспроводного датчика, и он должен работать только для фреймов данных только 2 или 3 ряда.

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

Данные, которые я использую, взяты из .xlsx файл с тремя столбцами: «ID», «Температура» и «Дата». Тест на выбросы, который я применяю к своему алгоритму, - это среднее абсолютное отклонение:

dfn=df[(np.abs(stats.zscore(df['Temperature']))<4)]

Сообщение об ошибке, которое я получаю при попытке использовать алгоритм для 9 строк данных, выглядит следующим образом:

/home/.../scipy/stats/stats.py:2419: RuntimeWarning: invalid value encountered in true_divide
 return (a - mns) / sstd
Metodo3in.py:20: RuntimeWarning: invalid value encountered in less

Тогда код все равно выполняется, но я получаю:

Empty DataFrame
Columns: [ID,Temperature,Date]
Index:[]

Вопросы

  • Почему 10 - минимальное количество строк данных для stats.zscore на работу?
  • Есть ли какие-нибудь альтернативы, которые можно применить к меньшим фреймам данных? Возможна потеря точности.

Любая помощь будет принята с благодарностью!

1 Ответ

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

stats.zscore работает для любой длины входных данных больше 1. Проблема возникает, когда все температуры равны. В этом случае результатом zscore является все np.nan, что приводит к пустому фрейму данных результата, поскольку любое сравнение с nan дает False:

stats.zscore([1,1]), np.abs(stats.zscore([1,1])<4)
#(array([nan, nan]), array([False, False]))
stats.zscore([1,2]), np.abs(stats.zscore([1,2])<4)
#(array([-1.,  1.]), array([ True,  True]))

Поэтому вам нужно дополнительное условие "все значения равны" или помечены "abs (zscore) <4" </em>. Оператор «или» для серии - это побитовое «или» (|), которое не сокращает, т.е. второй операнд всегда оценивается, даже если первый уже равен True. Это приводит к предупреждению (но результат правильный, поскольку второе условие не имеет значения, если первое уже True). Чтобы подавить это предупреждение, вам нужно поймать и игнорировать его:

import warnings
with warnings.catch_warnings():
    warnings.simplefilter('ignore')
    dfn = df[df.Temperature.eq(df.Temperature[0]).all() | (np.abs(stats.zscore(df['Temperature']))<4)]
...