如何在numpy数组a中匹配数组b?排查匹配结果异常问题
Numpy二维坐标数组匹配异常问题分析
我有两个numpy坐标数组a (n, 2)和b (m, 2),每行对应一个点的x、y坐标:
a = [[x1, y1], [x2, y2], ..., [xn, yn]] b = [[x1, y1], [x2, y2], ..., [xm, ym]]
需要高效生成布尔掩码,标记a中存在于b的元素。理论上b应为a的子集,但实际用多种方法得到的结果为m + k(k远小于n或m),而非预期的m。
已预处理数据去除nan和无穷值,因数组过大无法用嵌套循环做相等校验(嵌套循环代码仅作参考):
import numpy as np mask = np.zeros(a.shape, dtype=bool) for i, p1 in enumerate(a): for j, p2 in enumerate(b): if p1[0] == p2[0] and p1[1] == p2[1]: mask[i] = True
尝试的匹配方法及结果
1. numpy.isin() 方法
最初使用该方法,代码如下:
mask = np.isin(a, b, assume_unique=False).all(axis=1) print(mask.sum())
结果超出预期。检查发现b无重复值,a有少量重复但远少于k。
2. Numba加速的分维度匹配方法
为验证问题,尝试基于Numba的方法,分别匹配x、y维度后取交集:
import numba as nb @nb.jit def is_in_set_nb(a, b): shape = a.shape a = a.ravel() n = len(a) result = np.full(n, False) set_b = set(b) for i in range(n): if a[i] in set_b: result[i] = True return result.reshape(shape) mask_x = is_in_set_nb(a[:, 0], b[:, 0]) mask_y = is_in_set_nb(a[:, 1], b[:, 1]) mask = np.zeros((a.shape[0], ), dtype=bool) mask[mask_x & mask_y] = True print(mask.sum())
结果仍为m + k。
3. numpy.in1d() 分维度匹配方法
尝试另一种分维度匹配方法:
mask_x = np.in1d(a[:, 0].flatten(), b[:, 0].flatten()) mask_y = np.in1d(a[:, 1].flatten(), b[:, 1].flatten()) mask = np.zeros((a.shape[0], ), dtype=bool) mask[mask_x & mask_y] = True
结果依旧是m + k。
验证发现
将a[mask]导出为.gpkg在QGIS中验证,发现a[mask]存在b中没有的额外点,且b中部分点缺失,数量与k相当。但重新导入这些点集做匹配校验,却显示缺失点都在b中,部分额外点也被判定在b中。
请问:是数据存在问题,还是匹配方法有误?若有问题,具体是什么?
内容的提问来源于stack exchange,提问作者blob
相关产品推荐
相关产品推荐

