Обрезано среднее с процентом в Python?

Я пытаюсь вычислить сокращенный средний, который исключает выбросы массива.

Я обнаружил, что существует модуль под названием scipy.stats.tmean, но для этого требуется, чтобы пользователь определял диапазон по абсолютному значению вместо процентных значений.

В Matlab мы имеем m = trimmean(X,percent), что делает именно то, что я хочу.

Есть ли у нас аналог в Python?

Ответы

Ответ 1

По крайней мере, для scipy v0.14.0 для этого есть специальная (но недокументированная?) функция:

from scipy import stats
m = stats.trim_mean(X, 0.1) # Trim 10% at both ends

который использовал stats.trimboth внутри.

Ответ 2

Edit:

Метод, описанный ранее (внизу этого ответа), будет иметь проблему с этим вводом:

1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6

Поскольку он не будет включать все 1 и 6 из-за того, что он имеет то же значение, что и предел.

На самом деле вы можете просто реализовать все это самостоятельно, следуя инструкциям в документации MatLab. По-видимому, это проще: D

Здесь код в Python 2:

from numpy import mean
def trimmean(arr, percent):
    n = len(arr)
    k = int(round(n*(float(percent)/100)/2))
    return mean(arr[k+1:n-k])

Вы можете использовать numpy.percentile или scipy.stats.scoreatpercentile, чтобы получить абсолютное значение.

from scipy.stats import tmean, scoreatpercentile
def trimmean(arr, percent):
    lower_limit = scoreatpercentile(arr, percent/2)
    upper_limit = scoreatpercentile(arr, 100-percent/2)
    return tmean(arr, limits=(lower_limit, upper_limit), inclusive=(False, False))

Вы должны попробовать с различными входами, чтобы проверить граничные случаи, чтобы получить именно то поведение, которое вы хотите.

Ответ 3

Здесь ручная реализация с использованием пола из математической библиотеки...

def trimMean(tlist,tperc):
    removeN = int(math.floor(len(tlist) * tperc / 2))
    tlist.sort()
    if removeN > 0: tlist = tlist[removeN:-removeN]
    return reduce(lambda a,b : a+b, tlist) / float(len(tlist))