2013-05-06 57 views
2

如何最好地查找python(有numpy)的一組數組(二維數組)中給定數組的出現次數? 這(簡體)我在Python代碼需要表示: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這正是我所需要的,但不適用於二維數組,只適用於整數。

+1

請勿使用單詞集。設定意味着最多隻能有一個給定的值。 – cmd 2013-05-06 15:02:04

+0

夠公平的,只是改變了它。 – 2013-05-06 15:08:20

回答

4

隨着1 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的加快速度。

+0

謝謝,這正是我所需要的。我將它擴展爲允許使用 'np.sum(haystack.dot(needle)== needle.shape [0],axis = 0)同時匹配多個圖案,並且針的形狀爲:numElementsPerPattern x numPatternsToMatch 。 – 2013-05-06 17:25:36

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功能做比較的,但它在代碼中肯定是乾淨的和易於理解的。

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]相同的形狀。

+0

我認爲你是一般情況下的最佳答案,因爲我的模式只包含1s和-1s,但是Jaime的答案在我的情況下更具性能(我的模式比這裏顯示的要大得多)。感謝您的回答! – 2013-05-06 17:14:14

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 

使用numpy.equal()用於比較返回基於輸入的比較TrueFalse元素的數組。 all()檢查數組中所有元素的真實性,然後檢查布爾元素列表中的sum()

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 
2

有點像@帶鉤的答案,但略有更簡潔。

np.sum(np.equal(A, b).all(axis=1))