web-dev-qa-db-ja.com

Python collections.Counter:most_common complex

Pythonの_most_common_オブジェクトによって提供される関数_collections.Counter_の複雑さは何ですか?

より具体的には、Counterは、カウント中に何らかのソートされたリストを保持し、nが数値である場合にO(n)より高速に_most_common_操作を実行できるようにしますカウンターに追加された(一意の)アイテムの数参考までに、n番目に頻度の高いトークンを見つけようとする大量のテキストデータを処理しています。

CPythonウィキで 公式ドキュメントTimeComplexityの記事 を確認しましたが、答えが見つかりませんでした。

31
Romain G

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カウントをヒープ化することから得られ、2番目の部分は_n - k_呼び出しからheappushpopメソッドを呼び出し、3番目の部分は最終ヒープのソートから得られますk要素。 _k <= n_なので、複雑さは次のようになります。

O(n log k)

_k = 1_の場合、複雑さが次のようであることを示すのは簡単です。

O(n)

34

ソース は、何が起こるかを正確に示します。

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.nlargestheapq.py で定義されています

6