当前位置: 首页 > 面试题库 >

在NumPy数组中搜索序列

阎星华
2023-03-14
问题内容

假设我有以下数组:

 array([2, 0, 0, 1, 0, 1, 0, 0])

我怎么在那里我有值序列发生指数:[0,0]?因此,在这种情况下的预期输出为:[1,2,6,7]

编辑:

1)请注意,这[0,0]只是一个序列。可能是[0,0,0][4,6,8,9][5,2,0],仅此而已。

2)如果将我的数组修改为:array([2, 0, 0, 0, 0, 1, 0, 1, 0, 0]),则具有相同序列的预期结果[0,0]将是[1,2,3,4,8,9]

我正在寻找一些NumPy快捷方式。


问题答案:

嗯,这基本上是template-matching problem图像处理中经常出现的问题。这篇文章中列出了两种方法:基于纯NumPy和基于OpenCV(cv2)。

方法1:
使用NumPy,可以2D在输入数组的整个长度上创建一组滑动索引。因此,每一行都是元素的滑动窗口。接下来,将每一行与输入序列匹配,这将带来broadcasting矢量化解决方案。我们寻找所有True表明完美匹配的行,因此它们将是匹配的起始索引。最后,使用这些索引,创建一个扩展到序列长度的索引范围,以提供所需的输出。实施将是-

def search_sequence_numpy(arr,seq):
    """ Find sequence in an array using NumPy only.

    Parameters
    ----------    
    arr    : input 1D array
    seq    : input 1D array

    Output
    ------    
    Output : 1D Array of indices in the input array that satisfy the 
    matching of input sequence in the input array.
    In case of no match, an empty list is returned.
    """

    # Store sizes of input array and sequence
    Na, Nseq = arr.size, seq.size

    # Range of sequence
    r_seq = np.arange(Nseq)

    # Create a 2D array of sliding indices across the entire length of input array.
    # Match up with the input sequence & get the matching starting indices.
    M = (arr[np.arange(Na-Nseq+1)[:,None] + r_seq] == seq).all(1)

    # Get the range of those indices as final output
    if M.any() >0:
        return np.where(np.convolve(M,np.ones((Nseq),dtype=int))>0)[0]
    else:
        return []         # No match found

方法2: 使用OpenCV(cv2),我们有一个内置函数template- matchingcv2.matchTemplate。使用此,我们将具有起始匹配索引。其余步骤将与以前的方法相同。这是使用的实现cv2

from cv2 import matchTemplate as cv2m

def search_sequence_cv2(arr,seq):
    """ Find sequence in an array using cv2.
    """

    # Run a template match with input sequence as the template across
    # the entire length of the input array and get scores.
    S = cv2m(arr.astype('uint8'),seq.astype('uint8'),cv2.TM_SQDIFF)

    # Now, with floating point array cases, the matching scores might not be 
    # exactly zeros, but would be very small numbers as compared to others.
    # So, for that use a very small to be used to threshold the scorees 
    # against and decide for matches.
    thresh = 1e-5 # Would depend on elements in seq. So, be careful setting this.

    # Find the matching indices
    idx = np.where(S.ravel() < thresh)[0]

    # Get the range of those indices as final output
    if len(idx)>0:
        return np.unique((idx[:,None] + np.arange(seq.size)).ravel())
    else:
        return []         # No match found

样品运行

In [512]: arr = np.array([2, 0, 0, 0, 0, 1, 0, 1, 0, 0])

In [513]: seq = np.array([0,0])

In [514]: search_sequence_numpy(arr,seq)
Out[514]: array([1, 2, 3, 4, 8, 9])

In [515]: search_sequence_cv2(arr,seq)
Out[515]: array([1, 2, 3, 4, 8, 9])

运行时测试

In [477]: arr = np.random.randint(0,9,(100000))
     ...: seq = np.array([3,6,8,4])
     ...:

In [478]: np.allclose(search_sequence_numpy(arr,seq),search_sequence_cv2(arr,seq))
Out[478]: True

In [479]: %timeit search_sequence_numpy(arr,seq)
100 loops, best of 3: 11.8 ms per loop

In [480]: %timeit search_sequence_cv2(arr,seq)
10 loops, best of 3: 20.6 ms per loop

似乎基于Pure NumPy的是最安全,最快的!



 类似资料:
  • 我真的被困在这件事上了,我很想得到你的帮助 我正在尝试编写一个带有签名的方法: 该方法以循环排序的二维数组和搜索num的值作为参数获取。如果值num在mat数组中,则该方法返回true。如果num值不在mat数组中,则该方法返回false。 如果第1季度的所有值都比第2季度的值小,第2季度的值比第3季度的值小,第3季度的值比第4季度的值小,那么该数组就是圆形的。 例如,以下数组是循环排序的: 如果

  • 问题内容: 我有具有重复值的numpy 2d数组。 我正在搜索这样的数组。 输入是列表,其编号类似于列0的值。我想要的最终结果是任何形式的结果行,例如数组,列表或元组 我的代码工作正常,但似乎不是pythonic。有没有更好的多值搜索策略? 就像只进行一次查找即可获取所有值的地方。 我的真实数组很大 问题答案: 方法1: 使用- 方法2: 使用-

  • 主要内容:numpy.sort(),numpy.argsort(),numpy.lexsort(),numpy.nonzero(),numpy.where(),numpy.extract(),numpy.argmax(),numpy.argmin()NumPy 提供了多种排序函数, 这些排序函数可以实现不同的排序算法。 排序算法特征主要体现在以下四个方面:执行速度,最坏情况下的复杂度,所需的工作空间以及算法的稳定性。下表列举了三种排序算法: NumPy排序算法 种类 速度 最坏复杂度 工作空间

  • 问题内容: 还有其他方法可以在Postgres的列中搜索某个值吗? 我目前安装的Postgres版本并 没有 让下面的语句: 数组示例: 该语句应返回数组包含的每一行。 问题答案: 对于相等性检查,您可以简单地: 在手册中阅读有关ANY / SOME的信息 。

  • 问题内容: 假设我们有以下js数组 是否有一个js内置函数或jQuery的一个,使用它可以搜索阵列 AR 的 VAL ? 谢谢 *_ _ _更新 _ _ * _ __** 根据 融合的 反应,我创建了这个原型 问题答案: 您可以创建一个哈希。

  • 问题内容: 假设我有一个带有任意值的矩阵A: 矩阵B包含A中元素的索引: 我该如何选择值一个指向由乙,即: 问题答案: 你可以使用 一个人也可以使用 样品运行