np.unique 统计频次需显式设 return_counts=true 才返回值与计数,且输入须为1d数组;浮点数慎用;若需原序频次或非负整数高频统计,可选 counter 或 bincount。

用 np.unique 统计频次最直接,但默认不返回计数
很多人调用 np.unique(arr) 后只看到去重结果,就以为它不能统计频次——其实只要加个参数就行。np.unique 默认只返回唯一值,但传入 return_counts=True 就能同时拿到值和对应出现次数。
- 必须显式写
return_counts=True,不能只靠索引或顺序推断 - 返回的是两个数组:
values, counts,顺序严格一一对应 - 输入必须是 1D 数组;如果是多维,得先
arr.flatten()或arr.ravel() - 对浮点数要小心:
0.1 + 0.2 != 0.3可能导致本该合并的值被拆成多个频次项
import numpy as np arr = np.array([1, 2, 2, 3, 3, 3]) vals, counts = np.unique(arr, return_counts=True) # vals → array([1, 2, 3]), counts → array([1, 2, 3])
想按原始顺序保留频次?np.unique 不行,得换思路
np.unique 总是按升序返回 values,如果你需要“第一次出现顺序”或“原数组遍历顺序”的频次排列(比如做直方图标签对齐),就不能依赖它。
- 用
collections.Counter+np.array转换:保留插入顺序(Python 3.7+),但失去 NumPy 向量化优势 - 手动构建索引映射:对小规模整数数组,可用
np.bincount(仅限非负整数) - 若只是想查某个特定值的频次,直接用
np.sum(arr == x)更快、更直观
# 对非负整数且范围不大时,bincount 最快 arr = np.array([0, 1, 1, 2, 2, 2]) counts = np.bincount(arr) # → array([1, 2, 3]),索引即值
np.bincount 快但限制多:只认非负整数,且会补零
np.bincount 是 NumPy 里真正“为频次而生”的函数,底层用 C 实现,比 unique 快一个数量级——但代价是苛刻的输入要求。
快速生成专业的 Python 脚本和应用代码。一键创建完整项目结构,支持CLI、API、爬虫、Bot、Django等多种项目类型,包含完整的项目结构、配置文件、依赖管理、测试、README和文档。
- 输入只能是非负整数(
int或uint类型),浮点数、负数、字符串都会报TypeError - 输出长度 = 最大值 + 1,中间缺失的整数位置填 0(比如
[0, 2, 2]→[1, 0, 2]) - 如果数据中最大值特别大(比如
10**6),但实际只用了其中几十个值,就会浪费大量内存 - 支持
weights参数,可做加权计数(比如带置信度的频次)
# 错误示例:浮点数直接崩 # np.bincount(np.array([1.0, 2.0])) → TypeError <h1>正确用法(需先转 int 且确认非负)</h1><p>arr = (np.random.rand(1000) * 5).astype(int) # [0, 4] counts = np.bincount(arr)</p>
遇到重复值太多或内存吃紧?避免一次性全量统计
当数组超大(比如上亿元素),即使 np.bincount 或 np.unique 也可能爆内存或变慢——这时候得控制粒度。
- 分块处理:用
np.array_split切成子数组,各自统计后再合并Counter或字典 - 如果只要 Top-K 频次,用
np.unique+np.argsort(counts)[::-1][:k]拿前 K 个,别全排序 - 对字符串或对象数组,
np.unique会回退到 Python 级比较,速度骤降;优先考虑pandas.Series.value_counts()(内部做了优化) - 注意
np.unique的axis参数:若在某轴上统计(如每行频次),别忘了指定,否则默认展平
真正卡住的往往不是“怎么写”,而是“要不要全量算”——尤其当唯一值数量接近原始数组长度时,频次统计本身已失去压缩意义。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










