中位数计算前必须排序,php无内置median()函数;需先用sort()或asort()排序,再取中间值,注意空数组、单元素及数值排序陷阱。

中位数计算前必须排序,PHP 没有内置中位数函数
PHP 标准库不提供 median() 这类函数,直接对未排序数组取中间索引会得到错误结果。中位数定义要求数据有序,所以第一步永远是排序——但选 sort() 还是 asort(),取决于你是否需要保留原始键名。如果只是数值统计,用 sort() 更安全;如果后续还要靠键名查来源(比如带 ID 的记录),就得用 asort() 并注意它会改变原数组顺序。
- 空数组或单元素数组要单独判断,否则取
$arr[floor((count($arr)-1)/2)]可能越界或逻辑错 -
sort()默认按字符串排序,数值[10, 2, 30]会被排成[10, 2, 30](因为 "10" SORT_NUMERIC 标志 - 浮点数、
null、字符串混排时,sort()行为不可靠,建议提前过滤或类型断言
奇数长度和偶数长度数组的中位数取法不同
长度为奇数时,中位数就是正中间那个值;长度为偶数时,是中间两个数的平均值。很多人只写 $arr[(int)(count($arr)/2)],这在偶数长度下会漏掉左中位数,导致结果偏高。
- 奇数:索引
$mid = floor(count($arr) / 2),取$arr[$mid] - 偶数:索引
$mid1 = count($arr) / 2 - 1和$mid2 = count($arr) / 2,取( $arr[$mid1] + $arr[$mid2] ) / 2 - 别用
(int)强转代替floor(),因为(int)2.9是2,但(int)-2.9是-2(向零截断),而中位数索引不会为负,这里影响不大,但习惯上用floor()更语义清晰
处理非数值数组时,array_filter() 和类型检查不能省
真实业务里数组常含 null、空字符串、对象甚至布尔值。直接排序再取中位,null 会被转成 0,false 也是 0,true 是 1,造成严重偏差。
- 用
array_filter($arr, 'is_numeric')只保留可转数字的项(注意:字符串"123"会被保留,"12.3"也会) - 如果只要纯整数或浮点数,改用
array_filter($arr, function($v) { return is_int($v) || is_float($v); }) - 过滤后务必检查结果是否为空,否则
sort()后取索引会报Undefined offset
性能敏感场景慎用 sort(),大数组考虑快速选择算法
对几万以上元素的数组求中位数,sort() 时间复杂度是 O(n log n),而「快速选择」(QuickSelect)平均能做到 O(n)。PHP 没原生实现,但小项目没必要自己写——除非你明确测出 sort() 成了瓶颈。
立即学习“PHP免费学习笔记(深入)”;
- 5000 元素以内,
sort()和手动快选差异几乎不可测 - 若真要优化,可用
usort()配合分区逻辑,但 bug 风险高,维护成本大 - 更现实的优化点是:避免重复排序——比如同一数组频繁求中位,先排好存起来
中位数看着简单,但 PHP 里最常翻车的是排序方式选错、偶数长度处理漏算、以及对非数值数据不做清洗。这三个点卡住,结果就完全不可信。









