2010-10-27 187 views
16

我有一个scipy数组,例如有效的方法来计算Python中的numpy/scipy数组中的唯一元素

a = array([[0, 0, 1], [1, 1, 1], [1, 1, 1], [1, 0, 1]]) 

我要计数阵列中的每个独特的元件的出现的次数。例如,对于上面的数组a,我想知道有[1,0,1]出现1次,[1,1,1]出现2次,出现[1,0,1]出现1次。

一种方式我认为这样做是:

from collections import defaultdict 
d = defaultdict(int) 

for elt in a: 
    d[elt] += 1 

有没有更好/更有效的方式?

谢谢。

+0

Numpy/Scipy在您的示例代码中的用法在哪里?或者,这只是为了达到这个想法,希望有一个Numpy/Scipy函数来解决这个问题? – Zelphir 2016-04-21 15:35:28

回答

8

如果使用Python 2.7(或3.1)坚持是不是一个问题,任何两个不同的Python版本是提供给您,也许如果你坚持哈希的像元组元素的新collections.Counter可能是东西给你:

>>> from collections import Counter 
>>> c = Counter([(0,0,1), (1,1,1), (1,1,1), (1,0,1)]) 
>>> c 
Counter({(1, 1, 1): 2, (0, 0, 1): 1, (1, 0, 1): 1})

虽然我没有对这两种方法做任何性能测试。

+5

defaultdict会更快。 John Machin在今天早些时候在一个答案中用时序表示了这一点(http://stackoverflow.com/questions/4036474/add-new-keys-to-a-dictionary-while-incrementing-existing-values)。 – 2010-10-27 21:48:20

+0

有用的知识:-)谢谢:-) – 2010-10-28 05:26:43

+1

虽然不按照OP的标题所要求的那样使用Numpy/Scipy。还提倡使用过时的Python版本。不知道这是一个好的答案。 – Zelphir 2016-04-21 15:36:33

1

为Python 2.6 <

import itertools 

data_array = [[0, 0, 1], [1, 1, 1], [1, 1, 1], [1, 0, 1]] 

dict_ = {} 

for list_, count in itertools.groupby(data_array): 
    dict_.update({tuple(list_), len(list(count))}) 
4

您可以按行字典顺序排列,并认准其中的行改变积分排序:

In [1]: a = array([[0, 0, 1], [1, 1, 1], [1, 1, 1], [1, 0, 1]]) 

In [2]: b = a[lexsort(a.T)] 

In [3]: b 
Out[3]: 
array([[0, 0, 1], 
     [1, 0, 1], 
     [1, 1, 1], 
     [1, 1, 1]]) 

... 


In [5]: (b[1:] - b[:-1]).any(-1) 
Out[5]: array([ True, True, False], dtype=bool) 

最后一个数组表示,前三排的不同第三行重复两次。

对于一和零的阵列可以编码值:

In [6]: bincount(dot(a, array([4,2,1]))) 
Out[6]: array([0, 1, 0, 0, 0, 1, 0, 2]) 

字典也可以使用。哪种方法最快将取决于您实际使用的阵列类型。

0

numpy_indexed包(免责声明:我是其作者)提供了一个类似于chuck发布的解决方案;这是一个很好的矢量化的。但与测试,一个很好的界面,以及更多相关的有用功能:

import numpy_indexed as npi 
npi.count(a) 
相关问题