检查两个3D numpy数组是否包含重叠的2D数组。

3

我有两个非常大的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是2D数组) 我需要找到重叠的numpy数组的数量,但不需要具体指定哪些。


不确定这是否是您想要的,但您可以检查每个维度的交集,然后相交结果。 - hodisr
2
你如何定义两个3D数组是否相交?你能添加最少的样本数据吗? 你能提供一些最小样本数据吗? - Divakar
“intersecting”是什么意思?在数学上,这个概念只适用于集合,而不适用于矩阵。 - Code-Apprentice
你期望的输出是什么? - Divakar
重叠图像数量 - Gderu
显示剩余2条评论
1个回答

8
我们可以利用一个我在几个问答中使用过的辅助函数,来利用views。为了得到子数组的存在性,我们可以在视图上使用np.isin或使用一个更费力的np.searchsorted方法 #1 : 使用np.isin -
# https://dev59.com/tqPia4cB1Zd3GeqP3cEw#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)

方法二:我们也可以利用np.searchsortedviews上进行操作 -
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

所以,这两个解决方案给出了在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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接