我有一个scipy数组,例如
a = array([[0, 0, 1], [1, 1, 1], [1, 1, 1], [1, 0, 1]])
我想计算数组中每个唯一元素的出现次数。例如,对于上面的数组a,我想知道[1次,0次,1次]出现1次,[1,1,1]出现1次,[1,0,1]出现1次。
我想到的一种方法是:
from collections import defaultdict
d = defaultdict(int)
for elt in a:
d[elt] += 1
有更好/更有效的方法吗?
感谢。
答案 0 :(得分: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})
我没有对这两种方法进行过任何性能测试。
答案 1 :(得分: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)
最后一个数组表示前三行不同,第三行重复两次。
对于1和0的数组,您可以对值进行编码:
In [6]: bincount(dot(a, array([4,2,1])))
Out[6]: array([0, 1, 0, 0, 0, 1, 0, 2])
也可以使用词典。哪种方法最快将取决于您实际使用的阵列类型。
答案 2 :(得分:1)
for 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))})
答案 3 :(得分:0)
numpy_indexed包(免责声明:我是它的作者)提供了类似于chuck发布的解决方案;这是一个很好的矢量化的。但是通过测试,一个很好的界面,以及更多相关的有用功能:
import numpy_indexed as npi
npi.count(a)