用 np.unique 查重复行必须显式指定 axis=0,否则默认展平数组导致结果错误;配合 return_index 和 return_inverse 可获取首次索引与逆映射,再通过 np.bincount 和 np.where 找出所有重复行原始位置。

用 np.unique 查重复行必须加 axis=0
不加 axis=0 默认展平数组,结果完全不是你想要的“按行去重”。比如 np.array([[1,2],[1,2],[3,4]]) 不加 axis 会变成 [1,2,1,2,3,4] 再去重,毫无意义。
正确做法是显式传 axis=0,让 np.unique 把每一行当一个整体比较:
import numpy as np a = np.array([[1,2],[1,2],[3,4]]) _, idx, inv = np.unique(a, axis=0, return_index=True, return_inverse=True)
这里 idx 是每组重复行中**首次出现的索引**,inv 是原数组各行在去重后结果中的对应位置(可用于统计重复次数)。
-
return_index=True才能拿到原始索引,否则只返回去重后的数组 -
return_inverse=True是判断哪些行重复的关键——如果某个inv值出现多次,对应行就重复 - 注意:
np.unique对浮点行做axis=0比较时,严格按值相等判断,不处理精度误差
找出所有重复行的原始位置(不止第一次)
仅靠 np.unique 的 return_index 只给第一次出现的位置,但你往往需要知道“哪几行彼此重复”。得靠 inv 配合 np.where 拆解:
立即学习“Python免费学习笔记(深入)”;
# 接上例 counts = np.bincount(inv) # 每个唯一行出现几次 dup_mask = counts[inv] > 1 # 哪些原始行属于重复组 dup_rows = np.where(dup_mask)[0] # 这些行的原始索引
这时候 dup_rows 就是所有重复行的下标,比如返回 [0,1] 表示第 0 行和第 1 行互为重复。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
- 别直接对
inv调用np.unique再计数——np.bincount更快且天然适配整数索引 - 如果数组行数极大(百万级),
bincount要求inv最大值不太大;否则改用scipy.stats.itemfreq或手动dict统计 -
axis=0下的np.unique时间复杂度接近 O(n log n),比手写 Python 循环快得多,但比哈希方案略慢
浮点数组重复行检测要小心精度问题
np.unique 在 axis=0 模式下不做任何容差比较。两个看似相同的浮点行,只要二进制表示有微小差异(比如 0.1 + 0.2 != 0.3),就会被当成不同行。
解决办法不是改 np.unique,而是预处理:
# 对浮点数组,先 round 再 unique(按需选精度) a_rounded = np.round(a, decimals=10) _, idx, inv = np.unique(a_rounded, axis=0, return_index=True, return_inverse=True)
- 不推荐用
np.isclose逐行比较——O(n²) 复杂度,大数据直接卡死 - 如果必须保留原始精度,可考虑把每行转成字符串再 hash(
pd.util.hash_pandas_object思路),但内存开销大 - 注意:
np.round对负无穷、NaN 等特殊值行为固定,但若数据含大量inf,需单独过滤
替代方案:用 Pandas 的 duplicated 更直观?
如果你已经用了 Pandas,或者不介意临时转 DataFrame,pd.DataFrame.duplicated 读起来更直白,还内置 keep 参数控制保留策略:
import pandas as pd df = pd.DataFrame(a) dup_mask = df.duplicated(keep=False) # True 表示该行有重复(包括自己) dup_indices = df[dup_mask].index.values
但它本质还是把数组转成 object 列再比较,底层没跳过哈希过程,性能通常略低于纯 NumPy 的 unique + bincount 方案。
- 纯 NumPy 环境下硬上 Pandas 会多引入依赖,不划算
- Pandas 版本
1.5+对数值列做了优化,但 axis=0 去重仍不如np.unique(..., axis=0)稳定 - 如果后续还要做分组、聚合,Pandas 流程更连贯;如果只是查重复,NumPy 更轻量
实际用的时候,axis=0 这个参数漏掉、浮点精度没处理、以及误以为 return_index 能返回所有重复位置,这三个地方最容易卡住人。

















