用np.unique处理二维数组重复行时必须指定axis=0,否则会展平数组导致丢失行结构;需保序时用return_index=True配合np.sort;浮点数行应先np.round再去重;大数据量需注意内存并考虑pandas替代。

用 np.unique 处理二维数组重复行时必须指定 axis=0
默认情况下 np.unique 会把整个二维数组展平再去重,结果变成一维,完全丢失行结构。这是最常踩的坑——看着代码没错,输出却对不上预期。
正确做法是显式传入 axis=0,让 NumPy 按行比较:
import numpy as np arr = np.array([[1, 2], [3, 4], [1, 2], [5, 6]]) unique_rows = np.unique(arr, axis=0) # 输出: array([[1, 2], [3, 4], [5, 6]])
注意:axis=0 表示“沿第 0 轴(行方向)操作”,即把每一行当作一个整体来比对;不写这参数就等于没做二维去重。
需要保留原始顺序?别用 np.unique 默认行为
np.unique 默认会排序,返回的行按字典序升序排列,和原始出现顺序无关。如果业务要求保持首次出现的位置(比如日志去重、采样保序),得换方法。
立即学习“Python免费学习笔记(深入)”;
- 用
np.lexsort+np.diff手动标记重复:先排序索引,再找相邻差异为 0 的行 - 更直接的是用
np.unique的return_index=True,再配合np.sort取最小索引:
_, idx = np.unique(arr, axis=0, return_index=True) unique_rows_in_order = arr[np.sort(idx)]
这个组合能确保每组重复行只保留**第一次出现的那行**,且整体顺序与原数组中首次出现位置一致。
快速生成专业的 Python 脚本和应用代码。一键创建完整项目结构,支持CLI、API、爬虫、Bot、Django等多种项目类型,包含完整的项目结构、配置文件、依赖管理、测试、README和文档。
处理浮点数行时,np.unique 可能失效
浮点计算误差会让本应相同的两行在数值上差一点(比如 0.1 + 0.2 != 0.3),np.unique 严格按位比较,就会误判为不同行。
解决思路不是四舍五入(会引入新误差),而是改用近似比较逻辑:
- 用
np.round(arr, decimals=10)统一截断精度,再传给np.unique - 或改用
scipy.spatial.distance.pdist+ 自定义阈值判断,但开销大,仅当精度要求极高时考虑
多数场景下 np.round(..., 10) 已足够稳定,比手动写循环快得多。
内存和性能:大数组别直接用 np.unique 不加限制
当数组行数超百万、列数较多时,np.unique 内部会构建临时索引结构,内存占用可能飙升到原数组的 2–3 倍,甚至触发 MemoryError。
可选缓解方式:
- 加
return_inverse=False, return_counts=False关掉不需要的返回值(默认全开) - 对列做预筛选:如果某列区分度高(如 ID 列),先用
np.unique在该列上去重,再对子集做全行比对 - 实在太大就分块处理,但要注意跨块重复行会被漏掉——得额外缓存上一块的唯一行做二次校验
真正的大数据量场景,NumPy 不是银弹;这时候该考虑 pandas.DataFrame.drop_duplicates(底层优化更好)或转到 Dask。

















