如何使用Numpy获取两个列表中的重复数组?是否有更优方法?
用Numpy高效查找两个数组中的重复行
嘿,这个问题问到点子上了!手动遍历每个元素去检查的方法不仅写起来麻烦,当你的数组规模变大时,效率会低得让人头疼。Numpy本身就提供了几种更高效的内置方案,完全不用自己造轮子。
方法一:利用np.intersect1d结合数组视图
这个方法的核心是把每行数组转换成一个可以被Numpy识别为单个元素的“视图”,这样就能用np.intersect1d直接找交集了,全程都是Numpy的C级别的高效操作,比Python循环快N倍。
示例代码:
import numpy as np # 假设我们有两个二维数组,每行代表一个"圆"的参数(比如x,y,r) circles_1 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) circles_2 = np.array([[4, 5, 6], [7, 8, 9], [10, 11, 12]]) # 定义一个工具函数,把每行转成连续字节的视图(不复制数据,只是改变解读方式) def row_to_view(arr): return arr.view(np.dtype((np.void, arr.dtype.itemsize * arr.shape[1]))) # 生成两个数组的行视图 view1 = row_to_view(circles_1) view2 = row_to_view(circles_2) # 找两个视图的交集 common_views = np.intersect1d(view1, view2) # 把视图转换回原数组格式 common_circles = common_views.view(circles_1.dtype).reshape(-1, circles_1.shape[1]) print(common_circles) # 输出:[[4 5 6] # [7 8 9]]
方法二:合并数组后用np.unique统计出现次数
这个方法更直观:把两个数组合并,然后找出在合并数组中出现次数≥2的行——这些就是同时存在于两个原数组中的重复行。
示例代码:
import numpy as np circles_1 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) circles_2 = np.array([[4, 5, 6], [7, 8, 9], [10, 11, 12]]) # 合并两个数组 combined = np.vstack((circles_1, circles_2)) # 按行去重,并返回每个唯一行的出现次数 unique_rows, counts = np.unique(combined, axis=0, return_counts=True) # 筛选出出现次数≥2的行(即两个原数组都存在的行) common_circles = unique_rows[counts >= 2] print(common_circles) # 输出和上面一样
注意事项
- 如果你的数组是浮点型,要小心浮点精度问题!比如两个看起来相同的浮点数,可能因为计算误差导致字节层面不同,这时候上面的方法会失效。这种情况可以先对数组做四舍五入(比如
np.round(arr, decimals=6)),或者用基于容差的比较(不过这种情况效率会稍低,需要结合广播和np.allclose来处理)。 - 这两种方法的时间复杂度都远低于遍历:遍历是O(m*n),而Numpy的内置方法是O(m log m + n log n)级别,数据量越大,优势越明显。
内容的提问来源于stack exchange,提问作者uioporqwerty
相关产品推荐
相关产品推荐

