Manera eficiente de contar elementos únicos en una matriz en números / puntos en Python

Tengo una matriz Scipy, por ejemplo,

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

Quiero contar el número de ocurrencias de cada elemento único en la matriz. Por ejemplo, para la matriz anterior a, quiero decir que hay 1 aparición de [0, 0, 1], 2 apariciones de [1, 1, 1] y 1 aparición de [1, 0, 1].

Una forma en que pensé en hacerlo es:

 from collections import defaultdict d = defaultdict(int) for elt in a: d[elt] += 1 

¿Hay una manera mejor / más eficiente?

Gracias.

Si quedarse con Python 2.7 (o 3.1) no es un problema y cualquiera de estas dos versiones de Python está disponible para usted, tal vez las nuevas colecciones. El encuentro podría ser algo para usted si se adhiere a elementos hashable como tuplas:

 >>> 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}) 

Sin embargo, no he hecho ninguna prueba de rendimiento en estos dos enfoques.

Puede ordenar la matriz por lexicografía por filas y buscar puntos donde cambian las filas:

 In [1]: a = array([[0, 0, 1], [1, 1, 1], [1, 1, 1], [1, 0, 1]]) In [2]: b = a[lexsort(aT)] 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) 

La última matriz dice que las tres primeras filas difieren y la tercera fila se repite dos veces.

Para matrices de unos y ceros puedes codificar los valores:

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

También se pueden utilizar diccionarios. Cuál de los diversos métodos será más rápido dependerá del tipo de arreglos con los que realmente esté trabajando.

para 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))}) 

El paquete numpy_indexed (descargo de responsabilidad: soy su autor) proporciona una solución similar a la publicada por chuck; que es muy bien vectorizado. Pero con pruebas, una interfaz agradable y muchas otras funciones útiles relacionadas:

 import numpy_indexed as npi npi.count(a)