我无法解释
trim_mean()
中 Scipy.stats
的行为。
我了解到,截尾均值在丢弃概率分布的给定部分后计算一系列数字的平均值。
在以下示例中,我得到的结果为 6.1111
from scipy.stats import trim_mean
data = [1, 2, 2, 3, 4, 30, 4, 4, 5]
trim_percentage = 0.05 # Trim 5% from each end
result = trim_mean(sorted(data), trim_percentage)
print(f"result = {result}")
结果 = 6.111111111111111
但是,我预计 1 和 30 将被删除,因为它们位于第 5 个百分点以下且高于第 95 个百分点。
当我手动执行时:
import numpy as np
data = [1, 2, 2, 3, 4, 30, 4, 4, 5]
p5, p95 = np.percentile(data, [5, 95])
print(f"The 5th percentile = {p5}\nThe 95th percentile = {p95}")
trim_average = np.mean(list(filter(lambda x: x if p5 < x < p95 else 0, data)))
print(f"trimmed average = {trim_average}")
我得到了这个:
第 5 个百分位数 = 1.4
第 95 个百分位数 = 19.999999999999993
修剪平均值 = 3.4285714285714284
这是否意味着
trim_mean()
单独处理每个数字并假设 均匀分布? proportiontocut
被解释为“切断分布的两个尾部的分数”。但如果不考虑分布,为什么会表现得像呢?
文档没有提及任何关于分布假设或百分位数的内容;正如您所注意到的,它切断了值的fraction。您有 9 个值,9 个值中的 5% 是 0.45 个值。但是,它无法截取值的一小部分。它指出它
如果比例导致非整数切片索引,则切片较少
在您的情况下,0.45 小于 1,因此在取平均值之前从两端删除零值。
您可以验证当
proportiontocut
超过1/len(data)
时结果发生变化:
from scipy import stats
x = [1, 2, 2, 3, 4, 30, 4, 4, 5]
p = 1/9
eps = 1e-15
stats.trim_mean(x, p-eps) # 6.111111111111111
stats.trim_mean(x, p+eps) # 3.4285714285714284