Python中对象most_common
提供的函数的复杂度是多少?collections.Counter
更具体地说,是Counter
在计数时保留某种排序列表,允许它比何时添加到计数器的(唯一)项目数most_common
更快地执行操作?供您参考,我正在处理大量文本数据,试图找到第 n 个最常见的标记。O(n)
n
我查看了CPython wiki 上的官方文档和TimeComplexity 文章,但找不到答案。
Python中对象most_common
提供的函数的复杂度是多少?collections.Counter
更具体地说,是Counter
在计数时保留某种排序列表,允许它比何时添加到计数器的(唯一)项目数most_common
更快地执行操作?供您参考,我正在处理大量文本数据,试图找到第 n 个最常见的标记。O(n)
n
我查看了CPython wiki 上的官方文档和TimeComplexity 文章,但找不到答案。
从collections.py的源代码中,我们看到如果我们不指定返回元素的数量,则most_common
返回一个排序的计数列表。这是一个O(n log n)
算法。
如果我们使用most_common
返回k > 1
元素,那么我们使用heapq.nlargest
. 这是一种O(k) + O((n - k) log k) + O(k log k)
算法,对于小常数非常有用k
,因为它本质上是线性的。O(k)
部分来自对初始计数的堆放,k
第二部分来自n - k
对方法的调用,heappushpop
第三部分来自对最终k
元素堆的排序。因为k <= n
我们可以得出结论,复杂性是:
O(n log k)
如果k = 1
那么很容易证明复杂性是:
上)
源代码准确显示了发生的情况:
def most_common(self, n=None):
'''List the n most common elements and their counts from the most
common to the least. If n is None, then list all element counts.
>>> Counter('abracadabra').most_common(3)
[('a', 5), ('r', 2), ('b', 2)]
'''
# Emulate Bag.sortedByCount from Smalltalk
if n is None:
return sorted(self.iteritems(), key=_itemgetter(1), reverse=True)
return _heapq.nlargest(n, self.iteritems(), key=_itemgetter(1))
heapq.nlargest
在heapq.py中定义