Как заменить значения выбросов ближайшим значением, например, функцией filloutlier в Matlab?

Мне нужно воспроизвести функцию filloutliers(someList,'nearest','mean'), которая существует в Matlab.

У меня есть следующий код, который работает в основном правильно. Однако, когда я даю ему набор данных, он заменяет неправильное значение. Он заменяет 453,675231 на 0 вместо -211,71818100000002. Я пытался изменить функцию compareNeighbors множеством разных способов, но, честно говоря, совершенно не понимаю, что делать на этом этапе.

Я добавлю данные, чтобы вы могли просто скопировать и вставить их, и это должно работать. Если я переключу < на > в функции compareNeighbors, это сработает для этого примера, но не для других.

import numpy as np
from math import sqrt
from statistics import stdev as std

def compareNeighbors(before, current, after):
    valBefore = (before - current)
    valAfter = (after - current)

    print(valBefore)
    print(valAfter)

    return(valBefore < valAfter) 

def findNearestValue(data, before, current, after):
    before = before if before > -1 else 0
    after = after if after < len(data) else len(data) - 1

    valBefore = data[before] if before != current else 10000000000
    valAfter = data[after] if after != current else 10000000000

    return valBefore if compareNeighbors(valBefore, valAfter, data[current]) else valAfter

def getOutlierLists(data, distance):
    outlierList = []
    outlierList.extend(data[data > distance].tolist())
    outlierList.extend(data[data < -distance].tolist())

    outlierListIndecies = [i for i, j in enumerate(data) if j in outlierList]

    return(outlierList, outlierListIndecies)

def filloutliers(data):
    stad = std(data)
    mean = np.mean(data)
    distance = 3*stad + mean

    (outlierList, outlierListIndecies) = getOutlierLists(data, distance)

    print(outlierList, " | ", outlierListIndecies, " | ", distance, " | ", mean)

    for i in range(len(outlierList)):
        data[outlierListIndecies[i]] = findNearestValue(data, outlierListIndecies[i] - 1, outlierListIndecies[i], outlierListIndecies[i] + 1)

    (outlierList, outlierListIndecies) = getOutlierLists(data, distance)

    if (len(outlierList) != 0):
        for i in reversed(range(len(outlierList))):
            data[outlierListIndecies[i]] = findNearestValue(data, outlierListIndecies[i] - 1, outlierListIndecies[i], outlierListIndecies[i] + 1)

    return data

Значение выброса: [453.675231]
Позиция в массиве: [46]
Максимальное значение для которого значение является выбросом: +/-415,67922821410116
Среднее значение: 99,86239028000001

Входные данные:
[0.0, 195.47146400000003, 0.0, 143.1795457, 19.7727047, 0.0, 37.9259413, 67.4346233, 175.714837, 140.72522700000002, 42.116339999999994, 0.0, 11.829232000000005, 0.0 , 225.20435399999997, 25.939856999999996, 9.875561000000005, 0.0, 30.22819100000001, 141.658386, 191.42069600000002, 182.45 1406, 188.27667599999998, 0.0, 192.48585400000002, 0.0, 79.817566, 94.469158, 97.0669257, 153.0584423, 87.5491337, 0.0, 87.5491337, 0.0, 377.6008777, 176.6662877, 397.683778, 82.18773, 136.917358, 79.201378, 57. 71598, 1.795560000000009, 1.795560000000009, 19.405960000000007, 135.51628, 0.0, 453.675231, 211.71818100000002, 109.460083 , 13.761809999999997, 0.0, 114.462883, 7.609375, 159.630814, 9.943822999999998, 0.0, 93.460329, 55.87061700000001, 46.083324000000005, 58.686195999999995, 18.636627, 0.0, 22.81034900 0000002, 144.659505, 0.0, 267.669085, 290.303405, 110.52316300000001, 52.656178, 110.52316300000001, 52.656178, 123.2650860 0000001, 61.89890700000001, 158.23855600000002, 194.428161, 181.365445, 264.36523, 0.0, 274.60668, 48.543030000000016, 308.51727600000004, 357.209626, 24.18412, 46.621155, 70.805275, 181.781889, 364.741453, 0.0, 143.6235 4900000003, 0.0, 4.201691000000004, 0.0, 0.0, 0.0, 135.2808976, 87.3988186, 216.920091, 84.215256, 161.518512, 0.0]

Выходные данные:
[0.0, 195.47146400000003, 0.0, 143.1795457, 19.7727047, 0.0, 37.9259413, 67.4346233, 175.714837, 140.72522700000002, 42.116339999999994, 0.0, 11.829232000000005, 0.0 , 225.20435399999997, 25.939856999999996, 9.875561000000005, 0.0, 30.22819100000001, 141.658386, 191.42069600000002, 182.45 1406, 188.27667599999998, 0.0, 192.48585400000002, 0.0, 79.817566, 94.469158, 97.0669257, 153.0584423, 87.5491337, 0.0, 87.5491337, 0.0, 377.6008777, 176.6662877, 397.683778, 82.18773, 136.917358, 79.201378, 57. 71598, 1.795560000000009, 1.795560000000009, 19.405960000000007, 135.51628, 0.0, 0.0, 211.71818100000002, 109.460083, 13.76 1809999999997, 0.0, 114.462883, 7.609375, 159.630814, 9.943822999999998, 0.0, 93.460329, 55.87061700000001, 46.083324000000005, 58.686195999999995, 18.636627, 0.0, 22.81034900 0000002, 144.659505, 0.0, 267.669085, 290.303405, 110.52316300000001, 52.656178, 110.52316300000001, 52.656178, 123.2650860 0000001, 61.89890700000001, 158.23855600000002, 194.428161, 181.365445, 264.36523, 0.0, 274.60668, 48.543030000000016, 308.51727600000004, 357.209626, 24.18412, 46.621155, 70.805275, 181.781889, 364.741453, 0.0, 143.6235 4900000003, 0.0, 4.201691000000004, 0.0, 0.0, 0.0, 135.2808976, 87.3988186, 216.920091, 84.215256, 161.518512, 0.0]

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
568
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

import numpy as np
from math import sqrt
from statistics import stdev as std

def isNotOutlier(point, upper, lower):
    return (point < upper and point > lower)

def findNearestValue(data, before, current, after, threshAbove, threshBelow):
    before = before if before > -1 else 0
    after = after if after < len(data) else len(data) - 1


    while(True):
        if (after < len(data) and isNotOutlier(data[after],threshAbove,threshBelow)):
            return data[after]
        after += 1
        if (before >= 0 and isNotOutlier(data[before],threshAbove,threshBelow)):
            return data[before]
        before -= 1


def getOutlierLists(data, distancePos, distanceNeg):
    outlierList = []
    outlierList.extend(data[data > distancePos].tolist())
    outlierList.extend(data[data < distanceNeg].tolist())

    outlierListIndecies = [i for i, j in enumerate(data) if j in outlierList]

    return(outlierList, outlierListIndecies)

def filloutliers(data):
    stad = std(data)
    mean = np.mean(data)
    distancePos = 3*stad + mean
    distanceNeg = (-3*stad) + mean

    (outlierList, outlierListIndecies) = getOutlierLists(data, distancePos, distanceNeg)
    
    toReplace =[]

    for i in range(len(outlierList)):
        toReplace.append(findNearestValue(data, outlierListIndecies[i] - 1, outlierListIndecies[i], outlierListIndecies[i] + 1, distancePos, distanceNeg))

    for i in range(len(outlierListIndecies)):
        data[outlierListIndecies[i]] = toReplace[i]
        
    return data

Другие вопросы по теме