2010-10-27 66 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) 
相關問題