【问题标题】:Is there a method in numpy that verifies if an array is contained in another array?numpy 中是否有一种方法可以验证一个数组是否包含在另一个数组中?
【发布时间】:2019-11-08 11:00:35
【问题描述】:

我想验证一个numpy数组是否是另一个数组中的连续序列。

例如

a = np.array([1,2,3,4,5,6,7])
b = np.array([3,4,5])
c = np.array([2,3,4,6])

预期的结果是:

is_sequence_of(b, a) # should return True
is_sequence_of(c, a) # should return False

我想知道是否有 numpy 方法可以做到这一点。

【问题讨论】:

标签: python numpy


【解决方案1】:

方法#1

我们可以用一个np.searchsorted -

def isin_seq(a,b):
    # Look for the presence of b in a, while keeping the sequence
    sidx = a.argsort()
    idx = np.searchsorted(a,b,sorter=sidx)
    idx[idx==len(a)] = 0
    ssidx = sidx[idx]
    return (np.diff(ssidx)==1).all() & (a[ssidx]==b).all()

请注意,这假定输入数组没有重复项。

示例运行 -

In [42]: isin_seq(a,b) # search for the sequence b in a
Out[42]: True

In [43]: isin_seq(c,b) # search for the sequence b in c
Out[43]: False

方法#2

另一个skimage.util.view_as_windows -

from skimage.util import view_as_windows

def isin_seq_v2(a,b):
    return (view_as_windows(a,len(b))==b).all(1).any()

方法#3

这也可以被认为是模板匹配问题,因此,对于 int 数字,我们可以使用 OpenCV 的内置函数 template-matchingcv2.matchTemplate(灵感来自 this post),就像这样 -

import cv2 
from cv2 import matchTemplate as cv2m

def isin_seq_v3(arr,seq):
    S = cv2m(arr.astype('uint8'),seq.astype('uint8'),cv2.TM_SQDIFF)
    return np.isclose(S,0).any()

方法#4

我们的方法可以受益于基于short-circuiting 的方法。因此,我们将使用带有numba 的一个来提高性能效率,就像这样 -

from numba import njit

@njit
def isin_seq_numba(a,b):
    m = len(a)
    n = len(b)
    for i in range(m-n+1):
        for j in range(n):
            if a[i+j]!=b[j]:
                break                
        if j==n-1:
            return True
    return False

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2015-10-28
  • 1970-01-01
  • 1970-01-01
  • 2022-12-01
  • 1970-01-01
  • 2021-06-23
  • 2019-10-21
相关资源
最近更新 更多