statistics.mode()要求唯一众数,否则抛statisticserror;推荐用collections.counter.most_common(1)获取首个众数及频次,或筛选全部众数。

用 statistics.mode() 算众数,但数据有并列就直接报错
Python 标准库的 statistics.mode() 只接受「严格唯一众数」的数据:只要有两个或以上值出现频次并列最高,它立刻抛出 StatisticsError。这不是 bug,是设计如此——它要的是「那个最常出现的值」,而不是「所有高频候选」。
常见错误现象:StatisticsError: no unique mode; found 2 equally common values
适用场景:你明确知道输入数据一定有唯一众数(比如某次问卷单选题的投票结果),且能容忍异常中断流程。
实操建议:
- 如果只是想快速验证是否存在唯一众数,用
try/except包一层statistics.mode() - 别把它当通用频次统计工具用——它不返回频次,也不处理多众数、空数据、非标量类型(如字典列表)
- 对浮点数或带误差的数值慎用,
1.0和1.0000001被视为不同值
collections.Counter.most_common(1) 是更稳的众数起点
真正干活时,Counter 才是 Python 里最可靠的第一站。它不假设唯一性,不挑数据类型(只要可哈希),还能顺手拿到频次。
示例:
from collections import Counter data = [1, 2, 2, 3, 3, 4] c = Counter(data) mode_val, mode_count = c.most_common(1)[0] # 得到 (2, 2) 或 (3, 2),取决于插入顺序
注意:most_common(1) 只取第一个最高频项,不保证是“最小值”或“最早出现”的众数;若需全部众数,得自己筛:[k for k, v in c.items() if v == max(c.values())]
容易踩的坑:
-
Counter对不可哈希类型(如list,dict)直接报TypeError,得先转成可哈希形式(如tuple) - 空列表传给
Counter().most_common(1)返回空列表,下标取[0]会IndexError,务必判空 - 字符串、字节串会被拆成字符/字节计数,不是按整个字符串算频次——要算词频得先
.split()或用Counter(words)
NumPy 的 scipy.stats.mode() 和 numpy.unique() 各有边界
科学计算场景下,别只盯着 scipy.stats.mode()——它默认返回第一个众数 + 频次,但 axis 参数行为反直觉:对二维数组,默认按列算,且返回的是 ModeResult 对象,不是裸数字。
更透明的做法是组合 numpy.unique():
import numpy as np arr = np.array([1, 2, 2, 3, 3]) vals, counts = np.unique(arr, return_counts=True) mode_val = vals[np.argmax(counts)]
性能与兼容性影响:
-
np.unique()自动去重排序,如果原始顺序重要(比如想保留首次出现位置),就得换scipy.stats.mode()或手写逻辑 -
scipy.stats.mode()对 NaN 不友好:默认把 NaN 当有效值计数;np.unique()则直接跳过 NaN(除非显式设return_counts=True并配合np.isnan()单独处理) - 整数数组用
np.bincount()更快,但它要求值是非负整数且范围不大,否则内存爆炸
自定义众数函数必须处理这三类边界
写一个真正鲁棒的 mode(),绕不开三个现实问题:空输入、多众数、非标量元素。
实操建议(以 list 输入为例):
- 空输入:统一返回
None或抛ValueError,别让调用方猜 - 多众数:提供参数
keep_all=False(默认只返一个)、keep_all=True(返 list),别硬编码成只取第一个 - 非标量元素(如
[{'a':1}, {'a':1}]):提前用json.dumps(..., sort_keys=True)或tuple(sorted(d.items()))归一化为可哈希形式
复杂点往往藏在「怎么定义相等」里:NaN == NaN 是 False,但它们该被算作同一个众数;datetime 有时区差异;字符串要考虑大小写和空白。这些没法靠一个函数兜底,得按业务定规则。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











