PythonのCounterクラスとは?初期化から算術演算まで徹底解説
Counter(カウンター)は、同じ値が何回追加されたかを記録するためのコンテナです。PythonのCounterクラスはcollectionsモジュールに含まれており、辞書(dict)のサブクラスとして実装されています。
PythonのCounterクラスの概要
Counterは、要素を辞書のキーとして、その出現回数を辞書の値として格納する「順序を持たないコレクション」と考えることができます。
カウント値には正の整数・0・負の整数のいずれも使用できます。キーと値に厳密な制限はありませんが、一般的には値は数値として扱うことを想定しており、それ以外のオブジェクト型を格納することも可能です。
Counterの初期化方法
Counterは3つの形式で初期化できます。コンストラクタには、①要素のシーケンス、②キーとカウントを含む辞書、③キーワード引数による「名前=カウント」のマッピング、のいずれかを渡せます。
import collections
print(collections.Counter(['a', 'b', 'c', 'a', 'b', 'b']))
print(collections.Counter({'a': 2, 'b': 3, 'c': 1}))
print(collections.Counter(a=2, b=3, c=1))これら3つの初期化方法の出力結果はすべて同じになります。
Counter({'b': 3, 'a': 2, 'c': 1})
Counter({'b': 3, 'a': 2, 'c': 1})
Counter({'b': 3, 'a': 2, 'c': 1})空のCounterを作成してupdate()で要素を追加する
引数なしでCounterを作成し、後からupdate()メソッドを使って要素を追加することもできます。
import collections
c = collections.Counter()
print('Initial:', c)
c.update('abcddcba')
print('Sequence:', c)
c.update({'a': 1, 'd': 5})
print('Dict:', c)実行結果
Initial: Counter()
Sequence: Counter({'a': 2, 'b': 2, 'c': 2, 'd': 2})
Dict: Counter({'d': 7, 'a': 3, 'b': 2, 'c': 2})このように、update()は既存のカウントに対して加算を行います。文字列を渡すと各文字の出現回数が、辞書を渡すと指定した数だけカウントが増えます。
カウント値へのアクセス
Counterに要素を格納した後は、通常の辞書と同じAPIでカウント値を取得できます。
import collections
c = collections.Counter('abcddcba')
for letter in 'abcdef':
print('%s : %d' % (letter, c[letter]))実行結果
a : 2 b : 2 c : 2 d : 2 e : 0 f : 0
Counterでは、存在しないキーにアクセスしてもKeyErrorは発生しません。入力に現れていない値のカウントは自動的に0として返されます(上記の例では「e」と「f」が該当します)。これは通常のdictとの大きな違いの一つです。
elements()メソッドで全要素を取得する
elements()メソッドは、Counterが把握しているすべての要素を生成するイテレータを返します。
import collections
c = collections.Counter('Python Counters')
c['z'] = 0
print(c)
print(list(c.elements()))実行結果
Counter({'t': 2, 'o': 2, 'n': 2, 'P': 1, 'y': 1, 'h': 1, ' ': 1, 'C': 1, 'u': 1, 'e': 1, 'r': 1, 's': 1, 'z': 0})
['P', 'y', 't', 't', 'h', 'o', 'o', 'n', 'n', ' ', 'C', 'u', 'e', 'r', 's']要素の順序は固定されておらず、カウントが0以下の項目(上記の例では「z」)は結果に含まれない点に注意してください。
most_common()で頻出要素を抽出する
n個の入力の中で共通して多く現れる要素とそのカウントを取得したい場合は、most_common()関数を使用します。
import collections
c = collections.Counter()
texts = '''Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa
qui officia deserunt mollit anim id est laborum.'''
for word in texts:
c.update(word.rstrip().lower())
print("テキスト内で最も多い5つの文字:")
for letter, count in c.most_common(5):
print("%s: %7d" % (letter, count))実行結果
テキスト内で最も多い5つの文字: i: 42 e: 38 t: 32 o: 29 u: 29
この例では、テキスト(ファイルでも同様に扱えます)に出現する文字をカウントして頻度分布を作成し、上位5件を出力しています。most_common()に引数を渡さなければ、すべての要素が頻度順のリストとして返されます。
算術演算と集合演算
Counterのインスタンスは、結果を集計するための算術演算および集合演算をサポートしています。
import collections
c1 = collections.Counter(['a', 'b', 'c', 'a', 'b', 'b'])
c2 = collections.Counter('alphabet')
print('C1:', c1)
print('C2:', c2)
print('\nCombined counts:')
print(c1 + c2)
print('\nSubtraction:')
print(c1 - c2)
print('\nIntersection (taking positive minimums):')
print(c1 & c2)
print('\nUnion (taking maximums):')
print(c1 | c2)実行結果
C1: Counter({'b': 3, 'a': 2, 'c': 1})
C2: Counter({'a': 2, 'l': 1, 'p': 1, 'h': 1, 'b': 1, 'e': 1, 't': 1})
Combined counts:
Counter({'a': 4, 'b': 4, 'c': 1, 'l': 1, 'p': 1, 'h': 1, 'e': 1, 't': 1})
Subtraction:
Counter({'b': 2, 'c': 1})
Intersection (taking positive minimums):
Counter({'a': 2, 'b': 1})
Union (taking maximums):
Counter({'b': 3, 'a': 2, 'c': 1, 'l': 1, 'p': 1, 'h': 1, 'e': 1, 't': 1})各演算の動作は次のとおりです。
- 加算(+):両方のカウントを合計します。
- 減算(-):カウントを差し引き、結果が0以下になる項目は除外されます。
- 積(&):共通する要素について、小さい方のカウント(正の値のみ)を採用します。
- 和(|):すべての要素について、大きい方のカウントを採用します。
演算によって新しいCounterが生成されるたびに、カウントが0または負の値になっている項目は自動的に破棄されます。この仕組みにより、常に有効なカウントだけが保持されるのです。
-
【初心者向け】Pythonのissuperset()メソッドの使い方をわかりやすく解説
はじめにこの記事では、Pythonのissuperset()メソッドについて、基本的な仕組みから実際のコード例まで詳しく解説します。issuperset()は、セット(集合)に対して使用できるメソッドで、引数として渡されたセットのすべての要素が、呼び出し元のセットに含まれているかどうかを判定します。呼び出し元のセットBが、引数のセットAのすべての要素を含んでいる場合 → True を返すセットAの要素がすべてBに含まれていない場合 → False を返すつまり、「BがAの上位集合(スーパーセット)であるかどうか」を判定するためのメソッドです。基本構文B.issuperset(A)この式は、Bが
-
Pythonオブジェクトを正しくクリーンアップする方法とは?__del__の落とし穴と解決策
Pythonにおけるオブジェクト破棄の基本Pythonでオブジェクトを正しくクリーンアップするには、ガベージコレクションと__del__メソッドの動作を理解することが重要です。Pythonでは、グローバル変数はNoneを代入することでクリーンアップされ、ローカル変数はスコープの終了時に自動的に破棄されます。オブジェクトが破棄されるタイミングでPythonから呼び出されるのが、デストラクタに相当する特殊メソッド__del__です。サンプルコード:Counterクラスでのクリーンアップ以下は、クラス内のすべてのオブジェクトをクリーンアップする例です。class Counter: Count