2

如何最好地在python(使用numpy)中的一组数组(二维数组)中找到给定数组的出现次数?这是(简化的)我需要用 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 ,它完全符合我的需要,但不适用于二维数组,仅适用于整数。

4

6 回答 6

4

1使用s 和s的数组-1,性能方面没有什么比使用 s 更好的了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

这个怎么样?它不使用 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 回答
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 比较基于输入的比较返回一个或元素numpy.equal()的数组。检查数组中所有元素的真实性,然后检查布尔元素列表。TrueFalseall()sum()

于 2013-05-06T15:13:59.283 回答