统计报告里最容易被滥用、也最容易骗人的一个数字,是"平均"。当一组数据里混进少数极端值时,"均值"可能会给出一个完全违背直觉的结论。这篇文章用一个真实的矛盾数字,讲清楚什么时候该用中位数。
现象
某个分组统计里,出现了两个自相矛盾的数字:
组 A:
中位数: -0.01%
均值: +7.54%
中位数说这组"几乎没变",均值却说它"涨了 7.5%"。同一个组,两个统计量差出了天壤之别。如果只报告均值,你很可能得出"这组表现很好"的结论——但中位数明明白白地告诉你,这组的典型表现其实就是 0。
根因
原因在于组内存在极端离群值。算术均值是"所有值加起来除以个数",它对极大或极小的值极其敏感:只要有一个巨大的正数,整个均值就被拽上去;换成巨大的负数,均值就被拽下来。
举个直观的例子,一组 100 个数,99 个都是 0,只有 1 个是 754:
均值 = 754 / 100 = 7.54
中位数 = 0 (第 50、51 个数都是 0)
均值 7.54 完全不能代表这组数据的整体——因为实际上 99% 的观测值都是 0。均值被那一个离群值带偏了。
而中位数是"排序后位于中间的那个数",它只看位置、不看大小,所以一个再大的离群值也只能把排名往后推一位,不会改变中间值。这就是为什么二者会如此矛盾。
解决
第一,统计量改用中位数,尤其是在分布明显有长尾的时候:
import numpy as np
mean_val = np.mean(group) # 会被离群值带偏
median_val = np.median(group) # 更稳健,代表"典型值"
print(f"均值: {mean_val:.4f}")
print(f"中位数: {median_val:.4f}")
第二,必要时先剔除离群值再算平均。剔除要先定义规则,常见的是用四分位距(IQR):
q1, q3 = np.percentile(group, [25, 75])
iqr = q3 - q1
lo, hi = q1 - 1.5 * iqr, q3 + 1.5 * iqr
cleaned = group[(group >= lo) & (group <= hi)]
print(f"原始均值: {group.mean():.4f} (n={len(group)})")
print(f"去离群均值: {cleaned.mean():.4f} (n={len(cleaned)})")
第三,也是最容易被忽略的一步:在报告里说明用的是哪种统计量。很多误会的根源不是算错,而是"没说清楚"。当均值和中位数同时给出、并且说明各自含义时,读者就能自己判断。
延伸与预防
只要分布有长尾,"均值"就可能不是你想表达的东西。这句话适用于很多场景:
- 收入统计里,均值远高于中位数,因为少数高收入者拉高了平均;
- 耗时统计里,几个超长的请求把平均响应时间拉得极高;
- 收益统计里,少数暴涨的标的让"平均收益"看起来很美。
预防的做法是形成一个习惯:报告任何"平均"之前,先看一眼分布。 画个直方图、算一下最大值和最小值、比较一下均值和中位数的差距。如果二者差得远,就说明分布有长尾,这时候应该优先用中位数,或者同时给出两个并解释。
更全面一点,还可以加上分位数(P25 / P50 / P75)和标准差——它们一起,才能勾勒出分布的真正形状。一个孤零零的"均值",永远不足以支撑一个结论。