如何在两个Numpy数组中找出相同元素?代码异常排查及替代方案
问题分析与解决方法
首先来说说你写的这段代码哪里出问题了:
你循环遍历a中的每一行x,然后用x == b[:,None]做比较——这里的维度广播会让b[:,None]变成形状为(5,1,3)的数组,和x(形状(3,))比较后得到一个(5,1,3)的布尔数组。接着.all(1)是沿着第二个轴取全True,得到(5,3)的数组,再.any(0)是沿着第一个轴取任意True,得到(3,)的布尔数组。最后用这个布尔数组去索引x,得到的是x中那些在b的某一行里所有元素都出现过的单个元素,而不是判断整个行是否同时存在于b中。这完全偏离了你想要找整行公共元素的需求,所以结果不符合预期。
接下来给你几种可行的实现方法,都能得到你想要的结果:
方法一:利用Numpy结构化数组实现整行匹配
Numpy的np.isin默认不支持直接比较二维数组的行,但我们可以把每行转换成结构化数组的单个元素,这样就能用isin来判断行是否存在:
import numpy as np a = np.array([[262.5, 262.5, 45], [262.5, 262.5, 15], [262.5, 187.5, 45], [262.5, 187.5, 15], [187.5, 262.5, 45], [187.5, 262.5, 15], [187.5, 187.5, 45], [187.5, 187.5, 15]]) b = np.array([[262.5, 262.5, 45], [262.5, 262.5, 15], [3,3,5], [5,5,7], [8,8,9]]) # 将二维数组转换为结构化数组,每行视为一个独立元素 a_struct = a.view([('', a.dtype)] * a.shape[1]) b_struct = b.view([('', b.dtype)] * b.shape[1]) # 生成a中存在于b的行的掩码 mask = np.isin(a_struct, b_struct) # 提取符合条件的行 result = a[mask] print(result)
运行后输出:
[[262.5 262.5 45. ] [262.5 262.5 15. ]]
方法二:用集合(元组哈希)实现
因为Numpy数组不能直接作为集合的元素,我们可以把每行转换成元组(元组是可哈希的),然后利用集合的交集操作找出公共行:
import numpy as np a = np.array([[262.5, 262.5, 45], [262.5, 262.5, 15], [262.5, 187.5, 45], [262.5, 187.5, 15], [187.5, 262.5, 45], [187.5, 262.5, 15], [187.5, 187.5, 45], [187.5, 187.5, 15]]) b = np.array([[262.5, 262.5, 45], [262.5, 262.5, 15], [3,3,5], [5,5,7], [8,8,9]]) # 将a和b的行转换为元组集合 a_tuples = {tuple(row) for row in a} b_tuples = {tuple(row) for row in b} # 求交集后转换回数组 common_rows = np.array(list(a_tuples & b_tuples)) print(common_rows)
如果需要保持这些行在a中的原有顺序,可以改用列表推导:
common_rows = np.array([row for row in a if tuple(row) in b_tuples])
内容的提问来源于stack exchange,提问作者BAOLIAN
相关产品推荐
相关产品推荐

