我有两个numpy坐标数组,a (n, 2)
和b (m, 2)
,其中两个数组中的每一行对应于点的x
和y
坐标:
a = [[x1, y1], [x2, y2], ..., [xn, yn]]
b = [[x1, y1], [x2, y2], ..., [xm, ym]]
我试图找到一种有效的方法来创建一个布尔掩码,其中True对应于a
中b
的出现。理论上,b
应该是a
的子集,但这个条件并不确定。到目前为止,我尝试的解决方案给了我太多的结果(即。b
),我不太清楚为什么。因此,我想就可能发生的事情征求意见。
总之,我想实现一个面具,
a[mask] = b
已对数据进行预处理,以删除nan和无穷大值。因为a
和b
都非常大,所以只使用for循环进行相等性检查是不可行的:
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
所以我最初使用numpy's isin()
方法:
mask = np.isin(a, b, assume_unique=False).all(axis=1)
print(mask.sum())
但是这里我没有得到预期的输出,而是得到了m + k
,其中k
比n
或m
小几个数量级。
我已经检查了数组中的重复项:
unique_a = np.unique(a, axis=0)
unique_b = np.unique(b, axis=0)
这表明b
没有重复,a
确实有一些,但仍然比剩余的k
少。
为了验证错误确实可能存在于数据中,而不是找到包含点的方法,我尝试了另一种方法(在https://stackoverflow.com/a/62008597中描述):
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())
numpy's 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
相同。然而,将这些点集导入到python中并进行与上面相同的包含检查,结果表明缺失的点都包含在b
中,但也有一些额外的点,这不应该是??
所以我的问题是
数据或方法是否有问题,如果有,那是什么?
2条答案
按热度按时间zpgglvta1#
np.isin(a, b, assume_unique=False)
按元素检查是否包含:对于a
中的每个点(x, y)
,它首先检查x
是否在b
中的某处,然后检查y
是否在b
中的某处。.all(axis=1)
只是允许您检查x
和y
是否存在于b
中的某个位置,但不一定在同一行。要获得预期的结果,请使用structured array
view
的数据,以便numpy可以正确分组:llycmphe2#
摘要
这两种方法都会给予与预期不同的结果,但原因不同。
第一种方法
在
mask = np.zeros(a.shape, dtype=bool)
之后,掩码将具有形状(n,2)。最后,例如,所以
mask.sum()
将给予一个两倍于预期的数第二种方法
这种方法的问题是
np.isin
对第二个数组应用了flatten,结果不是点,而是坐标的数量与其他坐标的数量进行比较。范例:
测试结果:
可以看到,
[2, 0]
与set(0, 1, 2)
进行比较,而不是与[[0, 1], [2, 1]]
进行比较解决方案
我能提供的利用numpy的最有效的解决方案是:
所以这里我们仍然进行元素比较,但是我们将其减少到预期的1-d掩码