2

Pythonで(numpyを使用して)一連の配列(2次元配列)内で特定の配列の出現回数を見つけるのに最適な方法は? これは(簡略化された)Pythonコードで表現する必要があるものです:

patterns = numpy.array([[1, -1, 1, -1],
                   [1, 1, -1, 1],
                   [1, -1, 1, -1],
                   ...])
findInPatterns = numpy.array([1, -1, 1, -1])
numberOfOccurrences = findNumberOfOccurrences(needle=findInPatterns, haystack=patterns)
print(numberOfOccurrences) # should print e.g. 2

実際には、各配列がセット内でどのくらいの頻度で見つかるかを調べる必要があります。しかし、上記のコードで説明されている機能は、途中ですでに大いに役立っています。

ループを使用してそれを行うことができることはわかっていますが、これを行うためのより効率的な方法があるかどうか疑問に思っていましたか? グーグルは、私が必要とすることを正確に行う numpy.bincount のみを許可しましたが、2次元配列ではなく、整数のみを対象としています。

4

6 に答える 6

4

1s とs の配列では-1、パフォーマンスに関しては を使用することに勝るものはありませんnp.dot。すべてのアイテムが一致する場合 (およびその場合にのみ)、内積は行内のアイテムの数まで加算されます。だからあなたはすることができます

>>> haystack = np.array([[1, -1, 1, -1],
...                      [1, 1, -1, 1],
...                      [1, -1, 1, -1]])
>>> needle = np.array([1, -1, 1, -1])
>>> haystack.dot(needle)
array([ 4, -2,  4])
>>> np.sum(haystack.dot(needle) == len(needle))
2

これは、畳み込みベースの画像マッチングの一種のおもちゃの特定のケースであり、簡単に書き直して、完全な行よりも短いパターンを探し、FFT を使用して高速化することもできます。

于 2013-05-06T15:56:43.190 に答える
3
import numpy
A = numpy.array([[1, -1, 1, -1],
                 [1, 1, -1, 1],
                 [1, -1, 1, -1]])
b = numpy.array([1, -1, 1, -1])

print ((A == b).sum(axis=1) == b.size).sum()

これにより行の一致が行われ、探しているパターンにすべての値が一致する行を選択してカウントします。これには がbと同じ形状である必要がありA[0]ます。

于 2013-05-06T15:13:21.547 に答える
2

@Hookedの答えに似ていますが、少し冗長です。

np.sum(np.equal(A, b).all(axis=1))
于 2013-05-06T15:26:13.057 に答える
1

どうですか:

>>> from collections import Counter
>>> c
[[1, -1, 1, -1], [1, -1, 1, 1], [2, 3, 4, 5], [1, -1, 1, -1]]
>>> Counter(list(tuple(i) for i in c))[tuple(c[0])]
2
于 2013-05-06T15:14:26.407 に答える
0
>>> import numpy
>>> haystack = numpy.array([[1, -1, 1, -1], [1, 1, -1, 1], [1, -1, 1, -1]])
>>> needle = numpy.array([1, -1, 1, -1])
>>> sum([numpy.equal(hay, needle).all() for hay in haystack])
2

for comparisonを使用すると、入力の比較に基づいてまたは要素numpy.equal()の配列が返されます。配列内のすべての要素の真偽をチェックしてから、ブール要素のリストをチェックします。TrueFalseall()sum()

于 2013-05-06T15:13:59.283 に答える
0

これはどう?numpy は使用しませんが、十分にシンプルで、任意のサイズ/形状の行列で機能します。考え方は非常に単純です。配列を比較する代わりに、タプルを比較します (タプルはハッシュ可能であるため、ネイティブで簡単に比較できます)。

patterns = [[1, -1, 1, -1], 
            [1, 2, 3, 4], 
            [1, -1, 1, -1], 
            [1], 
            [], 
            [1, 1, 1, -1], 
            [1, -1, 1, -1]]
key = [1, -1, 1, -1]

def find_number_of_occurrences(needle, haystack):
    needle = tuple(needle)
    return len([straw for straw in haystack if tuple(straw) == needle])

print find_number_of_occurrences(key, patterns) # Prints 3

これはhaystack、一致する要素 (needles必要に応じて ) からリスト内包表記を構築し、このリストの長さを返します。numpy 機能を使用してこれを行う場合と比べて効率がどうなるかはわかりませんが、コードがクリーンでわかりやすいことは確かです。

于 2013-05-06T15:11:11.763 に答える