返回数组中子数组的索引

Olg*_*lga 7 python arrays numpy

我用Python numpy.

我有一个numpy数组may_a:

may_a = numpy.array([False, True, False, True, True, False, True, False, True, True, False])
Run Code Online (Sandbox Code Playgroud)

我有一个numpy数组may_b:

may_b = numpy.array([False,True,True,False])
Run Code Online (Sandbox Code Playgroud)

我需要在数组may_b中找到数组may_a.

在输出中,我需要获取出现的索引.

out_index=[2,7]
Run Code Online (Sandbox Code Playgroud)

有人可以建议,我该怎么办out_index

Jai*_*ime 5

编辑以下代码确实允许执行基于卷积的相等性检查。它映射True1False-1。它还反转b,这是它正常工作所必需的:

def search(a, b) :
    return np.where(np.round(fftconvolve(a * 2 - 1, (b * 2 - 1)[::-1],
                                         mode='valid') - len(b)) == 0)[0]
Run Code Online (Sandbox Code Playgroud)

我已经检查过它提供与as_strided各种随机输入的方法相同的输出,它确实如此。我也对两者进行了计时,卷积只开始得到大约 256 个项目的大量搜索标记。


这似乎有点矫枉过正,但是对于布尔数据,您可以使用(滥用?)卷积:

In [8]: np.where(np.convolve(may_a, may_b.astype(int),
   ...:                      mode='valid') == may_b.sum())[0]
Out[8]: array([2, 7])
Run Code Online (Sandbox Code Playgroud)

对于较大的数据集,使用以下方法可能会更快scipy.signal.fftconvolve

In [13]: np.where(scipy.signal.fftconvolve(may_a, may_b,
   ....:                                   mode='valid') == may_b.sum())[0]
Out[13]: array([2, 7])
Run Code Online (Sandbox Code Playgroud)

不过你必须小心,因为现在输出是浮点数,四舍五入可能会破坏等式检查:

In [14]: scipy.signal.fftconvolve(may_a, may_b, mode='valid')
Out[14]: array([ 1.,  1.,  2.,  1.,  1.,  1.,  1.,  2.])
Run Code Online (Sandbox Code Playgroud)

因此,您可能会更好地使用以下内容:

In [15]: np.where(np.round(scipy.signal.fftconvolve(may_a, may_b, mode='valid') -
   ....:                   may_b.sum()) == 0)[0]
Out[15]: array([2, 7])
Run Code Online (Sandbox Code Playgroud)


Jai*_*ime 5

一个更酷的方法,可能不是很好,但适用于任何dtype,是使用as_strided:

In [2]: from numpy.lib.stride_tricks import as_strided

In [3]: may_a = numpy.array([False, True, False, True, True, False,
   ...:                      True, False, True, True, False])

In [4]: may_b = numpy.array([False,True,True,False])

In [5]: a = len(may_a)

In [6]: b = len(may_b)

In [7]: a_view = as_strided(may_a, shape=(a - b + 1, b),
   ...:                     strides=(may_a.dtype.itemsize,) * 2)

In [8]: a_view
Out[8]: 
array([[False,  True, False,  True],
       [ True, False,  True,  True],
       [False,  True,  True, False],
       [ True,  True, False,  True],
       [ True, False,  True, False],
       [False,  True, False,  True],
       [ True, False,  True,  True],
       [False,  True,  True, False]], dtype=bool)

In [9]: numpy.where(numpy.all(a_view == may_b, axis=1))[0]
Out[9]: array([2, 7])
Run Code Online (Sandbox Code Playgroud)

你必须要小心,因为即使a_viewmay_a数据的视图,当它与创建may_b的临时数组进行比较时(a - b + 1) * b,这可能是大as和bs 的问题.

  • 也许你喜欢指出小事情......不使用`.itemsize`但是`.strides [0]`有点不太容易失败,以防数组先前被切片. (4认同)