检查两个 3D numpy 数组是不是包含重叠的 2D 数组
Posted
技术标签:
【中文标题】检查两个 3D numpy 数组是不是包含重叠的 2D 数组【英文标题】:Check if two 3D numpy arrays contain overlapping 2D arrays检查两个 3D numpy 数组是否包含重叠的 2D 数组 【发布时间】:2019-07-14 11:22:33 【问题描述】:我有两个非常大的 numpy 数组,它们都是 3D 的。我需要找到一种有效的方法来检查它们是否重叠,因为首先将它们都变成集合需要太长时间。我尝试使用我在此处找到的另一种解决方案来解决同样的问题,但适用于 2D 数组,但我没有设法使其适用于 3D。 这是 2D 的解决方案:
nrows, ncols = A.shape
dtype='names':['f'.format(i) for i in range(ndep)],
'formats':ndep * [A.dtype]
C = np.intersect1d(A.view(dtype).view(dtype), B.view(dtype).view(dtype))
# This last bit is optional if you're okay with "C" being a structured array...
C = C.view(A.dtype).reshape(-1, ndep)
(其中 A 和 B 是二维数组) 我需要找到重叠的 numpy 数组的数量,但不是特定的。
【问题讨论】:
不确定这是否是您的意图,但您可以检查每个暗淡的交点,然后与结果相交 没有。在我的场景中,在第二和第三维度中有一个对象。我想检查这些对象是否出现在另一个数组中,如果有,有多少。 如果两个 3D 数组相交,您将如何定义?你能添加最少的样本数据吗? “相交”是什么意思?在数学上,这个概念只适用于集合,不适用于矩阵。 对象是图像。图像是二维的,它们是一个数组。我想检查出现在一个数组中的某些图像是否也出现在另一个数组中。抱歉之前的解释不好 【参考方案1】:我们可以利用views
使用我在几个问答中使用过的辅助函数。为了获得子数组的存在,我们可以在视图上使用np.isin
,或者使用更费力的np.searchsorted
。
方法#1:使用np.isin
-
# https://***.com/a/45313353/ @Divakar
def view1D(a, b): # a, b are arrays
a = np.ascontiguousarray(a)
b = np.ascontiguousarray(b)
void_dt = np.dtype((np.void, a.dtype.itemsize * a.shape[1]))
return a.view(void_dt).ravel(), b.view(void_dt).ravel()
def isin_nd(a,b):
# a,b are the 3D input arrays to give us "isin-like" functionality across them
A,B = view1D(a.reshape(a.shape[0],-1),b.reshape(b.shape[0],-1))
return np.isin(A,B)
方法#2:我们还可以在views
上利用np.searchsorted
-
def isin_nd_searchsorted(a,b):
# a,b are the 3D input arrays
A,B = view1D(a.reshape(a.shape[0],-1),b.reshape(b.shape[0],-1))
sidx = A.argsort()
sorted_index = np.searchsorted(A,B,sorter=sidx)
sorted_index[sorted_index==len(A)] = len(A)-1
idx = sidx[sorted_index]
return A[idx] == B
因此,这两种解决方案为我们提供了 a
中的每个子数组在 b
中的存在掩码。因此,要获得我们想要的计数,它将是 - isin_nd(a,b).sum()
或 isin_nd_searchsorted(a,b).sum()
。
示例运行 -
In [71]: # Setup with 3 common "subarrays"
...: np.random.seed(0)
...: a = np.random.randint(0,9,(10,4,5))
...: b = np.random.randint(0,9,(7,4,5))
...:
...: b[1] = a[4]
...: b[3] = a[2]
...: b[6] = a[0]
In [72]: isin_nd(a,b).sum()
Out[72]: 3
In [73]: isin_nd_searchsorted(a,b).sum()
Out[73]: 3
大型数组的计时 -
In [74]: # Setup
...: np.random.seed(0)
...: a = np.random.randint(0,9,(100,100,100))
...: b = np.random.randint(0,9,(100,100,100))
...: idxa = np.random.choice(range(len(a)), len(a)//2, replace=False)
...: idxb = np.random.choice(range(len(b)), len(b)//2, replace=False)
...: a[idxa] = b[idxb]
# Verify output
In [82]: np.allclose(isin_nd(a,b),isin_nd_searchsorted(a,b))
Out[82]: True
In [75]: %timeit isin_nd(a,b).sum()
10 loops, best of 3: 31.2 ms per loop
In [76]: %timeit isin_nd_searchsorted(a,b).sum()
100 loops, best of 3: 1.98 ms per loop
【讨论】:
以上是关于检查两个 3D numpy 数组是不是包含重叠的 2D 数组的主要内容,如果未能解决你的问题,请参考以下文章