7

で Python を使用しnumpyます。

私はnumpy配列を持っていますmay_a:

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

私はnumpy配列を持っていますmay_b:

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

may_barrayで arrayを見つける必要がありますmay_a

出力では、出現のインデックスを取得する必要があります。

out_index=[2,7]

誰かが提案してもらえますか、どうすれば入手できout_indexますか?

4

5 に答える 5

5

EDIT次のコードは、畳み込みベースの等価チェックを実行することを許可します。およびにマップTrueされます。また、正常に動作するために必要な を逆にします。1False-1b

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

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])

大規模なデータセットの場合は、次の方法を使用する方が速い場合があります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])

ただし、出力が浮動小数点になり、丸めによって等価チェックが損なわれる可能性があるため、注意が必要です。

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

したがって、次のようなものを使用したほうがよい場合があります。

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])
于 2013-02-15T08:16:49.153 に答える
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])

a_viewただし、は のデータのビューですが、 の一時的な配列may_aと比較するとが作成されるため、大きなやでは問題になる可能性があるため、注意が必要です。may_b(a - b + 1) * bab

于 2013-02-15T08:53:10.200 に答える
3

これは、文字列検索の問題によく似ています。これらの文字列検索アルゴリズムの実装を避けたい場合は、次のようにして、非常に高速な文字列検索に組み込まれた python を悪用できます。

# I've added [True, True, True] at the end.
may_a = numpy.array([False, True, False, True, True, False, True, False, True, True, False, True, True, True])
may_b = numpy.array([False,True,True,False])

may_a_str = may_a.tostring()
may_b_str = may_b.tostring()

idx = may_a_str.find(may_b_str)
out_index = []
while idx >= 0:
    out_index.append(idx)
    idx = may_a_str.find(may_b_str, idx+1)

これは、ブール配列に対しては正常に機能するはずです。このアプローチを別の配列タイプに使用する場合は、2 つの配列のストライドが一致していることを確認し、out_index をそのストライドで除算する必要があります。

ループの代わりに正規表現モジュールを使用して文字列検索を行うこともできます。

于 2013-02-15T18:07:45.903 に答える
2

これは、他のブールデータでも機能するはずです。

In [1]: import numpy as np

In [2]: a = np.array([False, True, False, True, True, False, True, False, True, True, False])

In [3]: b = np.array([False,True,True,False])

In [4]: def get_indices(a, b):
   ...:     window = len(b)
   ...:     shape = a.shape[:-1] + (a.shape[-1] - window + 1, window)
   ...:     strides = a.strides + (a.strides[-1],)
   ...:     w = np.lib.stride_tricks.as_strided(a, shape=shape, strides=strides)
   ...:     return np.where(np.all(np.equal(w,b),1) == True)[0]

In [5]: get_indices(a,b)
Out[5]: array([2, 7])
于 2013-02-15T08:44:52.880 に答える
1

numpy がその機能を提供しているかどうかはわかりません。そうでない場合は、次の解決策があります。

import numpy

def searchListIndexs(array, target):
    ret = []
    iLimit = len(array)-len(target)+1
    jLimit = len(target)
    for i in range(iLimit):
        for j in range(jLimit):
            if array[i+j] != target[j]:
                break
        else:
            ret.append(i)
    return ret


may_a = numpy.array([False, True, False, True, True, False, True, False, True, True, False])
may_b = numpy.array([False,True,True,False])
out_index = searchListIndexs(may_a, may_b)
print out_index #If you are using Python 3, then use print(out_index) instead.
于 2013-02-15T08:07:09.930 に答える