Counter

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通りの初期化による結果は全て同じです。

$ python collections_counter_init.py
Counter({'b': 3, 'a': 2, 'c': 1})
Counter({'b': 3, 'a': 2, 'c': 1})
Counter({'b': 3, 'a': 2, 'c': 1})

空の Counter インスタンスはは引数無しで作成して update() メソッドで値を追加します。

import collections

c = collections.Counter()
print 'Initial :', c

c.update('abcdaab')
print 'Sequence:', c

c.update({'a':1, 'd':5})
print 'Dict    :', c

カウンタの数値は置き換えられるのではなく新しいデータに基づいて増加します。このサンプルでは a に対する数値が 3 から 4 になります。

$ python collections_counter_update.py
Initial : Counter()
Sequence: Counter({'a': 3, 'b': 2, 'c': 1, 'd': 1})
Dict    : Counter({'d': 6, 'a': 4, 'b': 2, 'c': 1})

カウンタにアクセスする

Counter が追加されると、その数値はディクショナリ API を使用して取り出すことができます。

import collections

c = collections.Counter('abcdaab')

for letter in 'abcde':
    print '%s : %d' % (letter, c[letter])

Counter は不明な要素に対して KeyError を発生させません。もし入力に対する数値(このサンプルの e のように)が存在しないなら、その数値は 0 です。

$ python collections_counter_get_values.py
a : 3
b : 2
c : 1
d : 1
e : 0

elements() メソッドは Counter に対して全ての要素を生成するイテレータを返します。

import collections

c = collections.Counter('extremely')
c['z'] = 0
print c
print list(c.elements())

要素の順番は保証されず、また要素の数がゼロ以下のときは含まれません。

$ python collections_counter_elements.py
Counter({'e': 3, 'm': 1, 'l': 1, 'r': 1, 't': 1, 'y': 1, 'x': 1, 'z': 0})
['e', 'e', 'e', 'm', 'l', 'r', 't', 'y', 'x']

最も頻度の高い入力値とその文字の現れた回数 n のシーケンスを生成するために most_common() を使用してください。

import collections

c = collections.Counter()
with open('/usr/share/dict/words', 'rt') as f:
    for line in f:
        c.update(line.rstrip().lower())

print 'Most common:'
for letter, count in c.most_common(3):
    print '%s: %7d' % (letter, count)

このサンプルは頻度分布を生成するためにシステム辞書の全ての単語に現れる文字を数えます。それから最も頻度の高いトップ3を表示します。 most_common() に引数を渡さないと、頻度の高い順番に全ての要素のリストを生成します。

$ python collections_counter_most_common.py
Most common:
e:  235331
i:  201032
a:  199554

算術演算

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

ある演算により新しい Counter が生成される毎に、ゼロかマイナスの数値を持つ要素は破棄されます。 a の数値は c1c2 で同じ数なので、引き算をするとゼロになります。

$ python collections_counter_arithmetic.py
C1: Counter({'b': 3, 'a': 2, 'c': 1})
C2: Counter({'a': 2, 'b': 1, 'e': 1, 'h': 1, 'l': 1, 'p': 1, 't': 1})

Combined counts:
Counter({'a': 4, 'b': 4, 'c': 1, 'e': 1, 'h': 1, 'l': 1, 'p': 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, 'e': 1, 'h': 1, 'l': 1, 'p': 1, 't': 1})
Bookmark and Share