Python中如何统计NumPy数组中各元素出现的次数_使用unique函数及其参数

Python中如何统计NumPy数组中各元素出现的次数_使用unique函数及其参数

Python

用np.unique统计频次需显式设return_counts=True,返回values和counts两个数组;多维数组须先扁平化;axis参数与return_counts=True互斥;非负整数可用更快的np.bincount,但不支持浮点、负数;浮点数需预处理防精度误差。

如何用 np.unique 统计数组中每个元素的出现次数

直接调用 np.unique 并设置 return_counts=True 即可拿到元素值和对应频次两个数组,这是最常用也最稳妥的方式。

常见错误是只写 np.unique(arr) 就以为能返回次数——它默认只去重并排序,不统计频次。

  • 必须显式传入 return_counts=True,否则返回值长度为1,不会包含计数结果
  • 返回顺序固定:values, counts = np.unique(arr, return_counts=True),不能颠倒
  • 输入必须是 1D 数组;若为多维,需先扁平化(arr.ravel()arr.flatten()

示例:

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])

为什么 axis 参数在统计频次时基本用不上

np.uniqueaxis 参数仅控制“沿哪个轴去重”,但**不支持按轴统计频次**。一旦指定 axisreturn_counts=True 会报错或行为异常(NumPy 1.20+ 报 ValueError: The 'axis' parameter is not supported when 'return_counts' is True)。

也就是说:要统计频次,就必须先展平;想保留结构维度做分块统计,得手动切片或用 scipy.stats.itemfreq(已弃用)或 np.bincount(仅限非负整数)替代。

  • 对二维数组逐行统计?用列表推导:[np.unique(row, return_counts=True) for row in arr]
  • 想统计每列出现最多的值?先转置再用 unique,但频次仍得单列算
  • axis=0axis=1 + return_counts=True 是无效组合,直接抛异常

np.bincountunique 快,但限制极多

当数组是**非负整数**且值域不太大(比如像素值、类别标签 0~255)时,np.bincount 是更快的选择,它内部用 C 实现计数,时间复杂度接近 O(n)。

爱派AiPy

融合LLM与Python生态的开源AI智能体

但它不处理浮点数、负数、字符串,也不返回实际出现的值(只返回下标为值、内容为频次的数组),容易误读结果。

  • np.bincount([0, 1, 1, 3])array([1, 2, 0, 1]),注意索引 2 处是 0(表示值 2 没出现)
  • 含负数?先偏移:arr_min = arr.min(); np.bincount(arr - arr_min),但得自己记偏移量
  • 含浮点数?必须先量化或转整数,否则报 TypeError: array cannot be safely cast to required type

遇到重复浮点数统计不准,不是 bug,是精度问题

浮点数在计算机中无法精确表示,np.unique 默认使用严格相等判断(==),所以 0.1 + 0.20.3 在 NumPy 中很可能被识别为不同元素。

这不是函数缺陷,而是浮点语义本身的问题。解决思路不是换函数,而是预处理:

  • 四舍五入到固定小数位:np.round(arr, decimals=5) 再传给 unique
  • np.isclose 手动聚类(适合小数组,性能差)
  • 改用 pandas.cut 分箱后统计,更适合分析场景

别指望 unique 自带容差参数——它没有,也没计划加。

本文地址:https://www.sztg.com.cn/article/668138.html

如非特殊说明,本站内容均来自于网友自主分享,如有任何问题均请联系我们进行处理!

猜您喜欢