np.unique()默认只返回去重排序数组,需设return_counts=true才同时返回值与频次;多维数组默认展平处理,按行/列统计需指定axis参数(numpy 1.20+)。

np.unique() 默认只返回去重后数组,不带计数
很多人一上来就写 np.unique(arr),发现结果只是排好序的唯一值,没看到频次——这是因为默认参数 return_counts=False。要拿到计数,必须显式打开开关。
常见错误现象:np.unique([1,2,2,3]) 返回 array([1, 2, 3]),但你其实想要每个值出现几次。
- 加
return_counts=True才能同时拿到值和频次,返回的是两个数组(values,counts) - 两者长度一致,一一对应,别直接用
counts[0]去猜哪个值——得靠下标对齐 - 如果原数组是多维,
np.unique()默认先展平再处理,不是按行/列统计;需要按轴统计得先用axis=参数(仅限 NumPy 1.20+)
想按行或列统计唯一组合?得用 axis 参数
比如二维数组每行看作一个整体,统计“哪几行重复了几次”,这时不能靠展平——否则会把不同行混在一起算。得用 axis 指定维度。
使用场景:统计用户行为日志中重复的请求序列、图像 patch 的重复模式等。
-
np.unique(arr_2d, axis=0)统计唯一行,返回去重后的二维数组 - 要同时要计数,同样得加
return_counts=True,但注意此时counts是一维数组,长度等于唯一行数 -
axis=1对应列方向;老版本 NumPy(axis,会报TypeError: unique() got an unexpected keyword argument 'axis' - 性能影响:开
axis时底层要做结构化比较,比一维慢不少,大数据量建议先转为tuple或view加速
count_nonzero + isin 组合更适合“查某个值出现几次”
如果你只关心某几个特定值的频次(比如统计数组里有多少个 0、多少个 -1),用 np.unique() 反而浪费——它会遍历全部值、排序、再拆分。
快速生成专业的 Python 脚本和应用代码。一键创建完整项目结构,支持CLI、API、爬虫、Bot、Django等多种项目类型,包含完整的项目结构、配置文件、依赖管理、测试、README和文档。
更轻量的做法是直接布尔索引 + 计数:
arr = np.array([0, 1, 0, -1, 0, 2]) np.count_nonzero(arr == 0) # → 3 np.count_nonzero(np.isin(arr, [0, -1])) # → 4
-
arr == x生成布尔数组,count_nonzero统计 True 个数,比sum()稍快且语义更清晰 -
np.isin(arr, values)支持多个目标值,适合白名单过滤场景 - 这种写法不排序、不建新数组,内存友好,尤其适合稀疏查询
- 注意
==对 NaN 不可靠,含缺失值时改用np.isnan()单独判断
unique 结果顺序固定但不可控,别依赖“首次出现位置”
np.unique() 返回的唯一值总是升序排列(数值类型)或字典序(字符串),不是按原始数组中首次出现顺序。这点容易被忽略,导致逻辑错位。
比如你想知道“第一个重复出现的元素是谁”,不能靠 unique()[0]——它只是最小值。
- 要保留首次出现顺序,得用
return_index=True,再配合argsort(indices)手动重排 - 或者改用
pd.Series(arr).drop_duplicates().values(需 Pandas),天然保序 - 字符串数组若含大小写混合,
unique默认区分大小写;不区分时得先统一转小写再算 - 浮点数相等判断本身有精度陷阱,
unique内部用的是精确相等,不是np.allclose;需要容差去重要自己 round 或用np.round(arr, decimals)预处理
实际用的时候,到底是调 np.unique 还是切片 + count_nonzero,取决于你是在“普查全部值”还是“抽查几个值”——前者绕不开 unique,后者真没必要让它全跑一遍。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










