我正在尝试计算数组的修剪平均值,它排除异常值。
我发现有一个名为scipy.stats.tmean
的模块,但它要求用户按绝对值而不是百分比值指定范围。
在Matlab中,我们有m = trimmean(X,percent)
,这正是我想要的。
我们在Python中有对应的吗?
答案 0 :(得分:18)
至少对于scipy v0.14.0,有一个专用的(但未记录的?)函数:
from scipy import stats
m = stats.trim_mean(X, 0.1) # Trim 10% at both ends
里面使用stats.trimboth
。
答案 1 :(得分:6)
修改:
我之前描述的方法(在本答案的底部)将对此输入产生问题:
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))
您应该尝试使用各种输入来检查边界情况,以获得您想要的行为。
答案 2 :(得分:0)
这是一个使用数学库中的floor的手动实现...
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))