Ответ 1
По крайней мере, для scipy v0.14.0 для этого есть специальная (но недокументированная?) функция:
from scipy import stats
m = stats.trim_mean(X, 0.1) # Trim 10% at both ends
который использовал stats.trimboth
внутри.
Я пытаюсь вычислить сокращенный средний, который исключает выбросы массива.
Я обнаружил, что существует модуль под названием scipy.stats.tmean
, но для этого требуется, чтобы пользователь определял диапазон по абсолютному значению вместо процентных значений.
В Matlab мы имеем m = trimmean(X,percent)
, что делает именно то, что я хочу.
Есть ли у нас аналог в Python?
По крайней мере, для scipy v0.14.0 для этого есть специальная (но недокументированная?) функция:
from scipy import stats
m = stats.trim_mean(X, 0.1) # Trim 10% at both ends
который использовал stats.trimboth
внутри.
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))
Вы должны попробовать с различными входами, чтобы проверить граничные случаи, чтобы получить именно то поведение, которое вы хотите.
Здесь ручная реализация с использованием пола из математической библиотеки...
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))