如何统计列表项的发生?
给定一个项目,我怎样才能在Python列表中计算它的出现?
>>> [1, 2, 3, 4, 1, 4, 1].count(1) 3
如果您使用的是Python 2.7或3,并且您希望每个元素的出现次数为:
>>> from collections import Counter >>> z = ['blue', 'red', 'blue', 'yellow', 'blue', 'red'] >>> Counter(z) Counter({'blue': 3, 'red': 2, 'yellow': 1})
计算列表中一个项目的出现次数
为了统计只有一个列表项的出现,你可以使用count()
>>> l = ["a","b","b"] >>> l.count("a") 1 >>> l.count("b") 2
统计列表中所有项目的出现次数也称为“统计”列表或创build计数器计数器。
用count()计算所有项目
要计算项目的出现次数,可以简单地使用列表理解和count()
方法
[[x,l.count(x)] for x in set(l)]
(或类似地用dict((x,l.count(x)) for x in set(l))
的字典dict((x,l.count(x)) for x in set(l))
)
例:
>>> l = ["a","b","b"] >>> [[x,l.count(x)] for x in set(l)] [['a', 1], ['b', 2]] >>> dict((x,l.count(x)) for x in set(l)) {'a': 1, 'b': 2}
用Counter()计数所有项目
或者,从collections
库中有更快的Counter
类
Counter(l)
例:
>>> l = ["a","b","b"] >>> from collections import Counter >>> Counter(l) Counter({'b': 2, 'a': 1})
Counter有多快?
我查了多lessCounter
是统计清单。 我用n
的几个值来尝试两种方法,看起来, Counter
以大约2的常数因子更快。
这是我使用的脚本:
from __future__ import print_function import timeit t1=timeit.Timer('Counter(l)', \ 'import random;import string;from collections import Counter;n=1000;l=[random.choice(string.ascii_letters) for x in range(n)]' ) t2=timeit.Timer('[[x,l.count(x)] for x in set(l)]', 'import random;import string;n=1000;l=[random.choice(string.ascii_letters) for x in range(n)]' ) print("Counter(): ", t1.repeat(repeat=3,number=10000)) print("count(): ", t2.repeat(repeat=3,number=10000)
而输出:
Counter(): [0.46062711701961234, 0.4022796869976446, 0.3974247490405105] count(): [7.779430688009597, 7.962715800967999, 8.420845870045014]
另一种方法来获取每个项目的出现次数,在一个字典中:
dict((i, a.count(i)) for i in a)
list.count(x)
返回x
出现在列表中的次数
请参阅: http : //docs.python.org/tutorial/datastructures.html#more-on-lists
如果你想一次统计所有的值,你可以使用numpy数组和bincount
非常快bincount
按照如下步骤进行
import numpy as np a = np.array([1, 2, 3, 4, 1, 4, 1]) np.bincount(a)
这使
>>> array([0, 3, 1, 1, 2])
给定一个项目,我怎样才能在Python列表中计算它的出现?
这里是一个例子列表:
>>> l = list('aaaaabbbbcccdde') >>> l ['a', 'a', 'a', 'a', 'a', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'd', 'd', 'e']
list.count
有list.count
方法
>>> l.count('b') 4
这适用于任何列表。 元组也有这个方法:
>>> t = tuple('aabbbffffff') >>> t ('a', 'a', 'b', 'b', 'b', 'f', 'f', 'f', 'f', 'f', 'f') >>> t.count('f') 6
collections.Counter
然后有collections品。计数器。 您可以将任何迭代器转储到Counter中,而不仅仅是一个列表,Counter将保留一个元素计数的数据结构。
用法:
>>> from collections import Counter >>> c = Counter(l) >>> c['b'] 4
计数器是基于Python字典,它们的关键是元素,所以密钥需要可散列。 它们基本上就像允许多余的元素进入它们的集合。
计算器的进一步用法。 collections.Counter
您可以从计数器中添加或减去迭代次数:
>>> c.update(list('bbb')) >>> c['b'] 7 >>> c.subtract(list('bbb')) >>> c['b'] 4
您也可以使用计数器进行多套操作:
>>> c2 = Counter(list('aabbxyz')) >>> c - c2 # set difference Counter({'a': 3, 'c': 3, 'b': 2, 'd': 2, 'e': 1}) >>> c + c2 # addition of all elements Counter({'a': 7, 'b': 6, 'c': 3, 'd': 2, 'e': 1, 'y': 1, 'x': 1, 'z': 1}) >>> c | c2 # set union Counter({'a': 5, 'b': 4, 'c': 3, 'd': 2, 'e': 1, 'y': 1, 'x': 1, 'z': 1}) >>> c & c2 # set intersection Counter({'a': 2, 'b': 2})
为什么不是pandas?
另一个答案表明:
为什么不使用pandas?
pandas是一个普通的图书馆,但它不在标准图书馆。 将它作为依赖添加是不重要的。
列表对象本身以及标准库中都有这种用例的内build解决scheme。
如果你的项目还不需要pandas,那么仅仅为了这个function而做它就是愚蠢的。
我今天有这个问题,并在我想检查SO之前推出了自己的解决scheme。 这个:
dict((i,a.count(i)) for i in a)
大列表真的很慢。 我的解决scheme
def occurDict(items): d = {} for i in items: if i in d: d[i] = d[i]+1 else: d[i] = 1 return d
实际上比Counter解决scheme快一点,至less对于Python 2.7来说。
为什么不使用pandas?
import pandas as pd l = ['a', 'b', 'c', 'd', 'a', 'd', 'a'] # converting the list to a Series and counting the values my_count = pd.Series(l).value_counts() my_count
输出:
a 3 d 2 b 1 c 1 dtype: int64
如果你正在寻找一个特定元素的数量,说一个 ,试试:
my_count['a']
输出:
3
# Python >= 2.6 (defaultdict) && < 2.7 (Counter, OrderedDict) from collections import defaultdict def count_unsorted_list_items(items): """ :param items: iterable of hashable items to count :type items: iterable :returns: dict of counts like Py2.7 Counter :rtype: dict """ counts = defaultdict(int) for item in items: counts[item] += 1 return dict(counts) # Python >= 2.2 (generators) def count_sorted_list_items(items): """ :param items: sorted iterable of items to count :type items: sorted iterable :returns: generator of (item, count) tuples :rtype: generator """ if not items: return elif len(items) == 1: yield (items[0], 1) return prev_item = items[0] count = 1 for item in items[1:]: if prev_item == item: count += 1 else: yield (prev_item, count) count = 1 prev_item = item yield (item, count) return import unittest class TestListCounters(unittest.TestCase): def test_count_unsorted_list_items(self): D = ( ([], []), ([2], [(2,1)]), ([2,2], [(2,2)]), ([2,2,2,2,3,3,5,5], [(2,4), (3,2), (5,2)]), ) for inp, exp_outp in D: counts = count_unsorted_list_items(inp) print inp, exp_outp, counts self.assertEqual(counts, dict( exp_outp )) inp, exp_outp = UNSORTED_WIN = ([2,2,4,2], [(2,3), (4,1)]) self.assertEqual(dict( exp_outp ), count_unsorted_list_items(inp) ) def test_count_sorted_list_items(self): D = ( ([], []), ([2], [(2,1)]), ([2,2], [(2,2)]), ([2,2,2,2,3,3,5,5], [(2,4), (3,2), (5,2)]), ) for inp, exp_outp in D: counts = list( count_sorted_list_items(inp) ) print inp, exp_outp, counts self.assertEqual(counts, exp_outp) inp, exp_outp = UNSORTED_FAIL = ([2,2,4,2], [(2,3), (4,1)]) self.assertEqual(exp_outp, list( count_sorted_list_items(inp) )) # ... [(2,2), (4,1), (2,1)]
我已经将所有build议的解决scheme(和一些新的解决scheme)与perfplot (我的一个小项目)进行了比较。
数一个项目
对于足够大的arrays,事实certificate
numpy.sum(numpy.array(a) == 1)
比其他解决scheme稍快。
计数所有项目
如前所述 ,
numpy.bincount(a)
是你想要的。
代码重现的情节:
from collections import Counter from collections import defaultdict import numpy import operator import pandas import perfplot def counter(a): return Counter(a) def count(a): return dict((i, a.count(i)) for i in set(a)) def bincount(a): return numpy.bincount(a) def pandas_value_counts(a): return pandas.Series(a).value_counts() def occur_dict(a): d = {} for i in a: if i in d: d[i] = d[i]+1 else: d[i] = 1 return d def count_unsorted_list_items(items): counts = defaultdict(int) for item in items: counts[item] += 1 return dict(counts) def operator_countof(a): return dict((i, operator.countOf(a, i)) for i in set(a)) perfplot.show( setup=lambda n: list(numpy.random.randint(0, 100, n)), n_range=[2**k for k in range(20)], kernels=[ counter, count, bincount, pandas_value_counts, occur_dict, count_unsorted_list_items, operator_countof ], equality_check=None, logx=True, logy=True, )
2。
from collections import Counter from collections import defaultdict import numpy import operator import pandas import perfplot def counter(a): return Counter(a) def count(a): return dict((i, a.count(i)) for i in set(a)) def bincount(a): return numpy.bincount(a) def pandas_value_counts(a): return pandas.Series(a).value_counts() def occur_dict(a): d = {} for i in a: if i in d: d[i] = d[i]+1 else: d[i] = 1 return d def count_unsorted_list_items(items): counts = defaultdict(int) for item in items: counts[item] += 1 return dict(counts) def operator_countof(a): return dict((i, operator.countOf(a, i)) for i in set(a)) perfplot.show( setup=lambda n: list(numpy.random.randint(0, 100, n)), n_range=[2**k for k in range(20)], kernels=[ counter, count, bincount, pandas_value_counts, occur_dict, count_unsorted_list_items, operator_countof ], equality_check=None, logx=True, logy=True, )
要计算具有通用types的不同元素的数量:
li = ['A0','c5','A8','A2','A5','c2','A3','A9'] print sum(1 for el in li if el[0]=='A' and el[1] in '01234')
给
3
,不是6
from collections import Counter country=['Uruguay', 'Mexico', 'Uruguay', 'France', 'Mexico'] count_country = Counter(country) output_list= [] for i in count_country: output_list.append([i,count_country[i]]) print output_list
输出列表:
[['Mexico', 2], ['France', 1], ['Uruguay', 2]]
您也可以使用内置模块operator
countOf
方法。
>>> import operator >>> operator.countOf([1, 2, 3, 4, 1, 4, 1], 1) 3
sum([1 for elem in <yourlist> if elem==<your_value>])
这将返回your_value的出现量