collections

【Python】Counterで要素数をカウントする(collections.Counter)

【Python】Counterで要素数をカウントする(collections.Counter)

リストの要素数をカウントする際に利用できるcollectionsモジュールのCounterについて解説します。

Counter(collectionsモジュール)

リストに含まれる要素数をカウントする場合、countメソッドを用いた方法があります。countメソッドの使い方は「リスト(list)の要素数をカウントする方法」でまとめていますので参考にしてください。

Pythonでは、collectionsモジュールにCounterという便利なカウントクラスがあり、様々な機能が提供されています。この記事では、collectionsモジュールのCounterで要素数をカウントする方法について紹介します。

Counterの使い方とメソッド

基本的な使い方

collectionsモジュールのCounterの基本的な使い方について、以下の例を使ってみていきます。

import collections

data = ["a", "a", "a", "b", "b", "c", "a", "b", "d", "d"]

counter = collections.Counter(data)

print(counter)
print(counter["a"])
【実行結果】
Counter({'a': 4, 'b': 3, 'd': 2, 'c': 1})
4

上記例では、リストdataに入れた文字のカウントをとっています。Counterを使用する場合には、collectionsモジュールをインポートします。

Counterをインスタンス化する際には、引数に対象リストを渡します。printしてみると分かりますが、リスト内の要素と要素数に関する辞書を含むようなデータとなっています。カウント数にアクセスする場合には、counter["a"]のようにアクセス可能です。

また、カウントの値を特定の値で増やしたい場合は、辞書のように扱うことが可能で以下のように+=演算子を使ってカウントを追加することもできます。

counter = collections.Counter()
for d in data:
    counter[d] += 2

なお、同じような処理は、同じくcollectionsモジュール内にあるdefaultdictを用いても実現できます。「defaultdictで規定値を持つ辞書を定義する(collections.defaultdict)」で例を紹介していますので参考にしてください。

上位を抽出するmost_commonメソッド

Counterにある便利なメソッドとして、カウント数上位を抽出するmost_commonメソッドがあります。most_commonメソッドは以下のように使用します。

import collections

data = ["a", "a", "a", "b", "b", "c", "a", "b", "d", "d"]

counter = collections.Counter(data)

print(counter)

print("=====")
# 上位1位までを抽出
print(counter.most_common(1))
# 上位2位までを抽出
print(counter.most_common(2))
# 引数なしだとすべて抽出
print(counter.most_common())
【実行結果】
Counter({'a': 4, 'b': 3, 'd': 2, 'c': 1})
=====
[('a', 4)]
[('a', 4), ('b', 3)]
[('a', 4), ('b', 3), ('d', 2), ('c', 1)]

most_commonメソッドの引数には上位n番目までということで、数字を渡します。1であれば上位1位を、2であれば上記2位までということになります。なお、引数に何も指定しない場合は、すべてを抽出します。

実行結果を見ていただければわかりますが、実行結果はタプルのリストとなっていますので取り扱いは簡単です。

カウント数のみを取り出すvaluesメソッド

Counterでカウントをとった後にカウント数のみを取り出す場合には、以下のようにvaluesメソッドを使用できます。

import collections

data = ["a", "a", "a", "b", "b", "c", "a", "b", "d", "d"]

counter = collections.Counter(data)
print(counter)

print("=====")
# カウント数の値のみをを取り出す
print(counter.values())
# カウント数の合計を計算する
print(sum(counter.values()))
【実行結果】
Counter({'a': 4, 'b': 3, 'd': 2, 'c': 1})
=====
dict_values([4, 3, 1, 2])
10

上記例のようにvaluesでカウント数の値のみを取り出すことができます。これにより、例えばsum関数を使ってカウント数の合計値を計算するようなことも簡単です。

valuesメソッドの返却値はdict_valuesクラスのインスタンスとなっているので、リストで扱いたい場合は、list(counter.values())のようにリストに変換して使うことができます。

なお、Counterでは4, 3, 2, 1という順で値が表示されていますが、dict_valuesでは、4, 3, 1, 2という順になっており、値の順が変わっています。これは、dict_valuesの順がキーの順によるもので違いが出ているためですので注意してください。

Counterの使用例

ファイル中の単語数をカウントする例

Counterの使用例として、読み込んだファイルの中にある単語数をカウントする例を見てみましょう。適当なテキストですが、以下のようなinput.txtというテキストファイルがあったとして、含まれる単語数をカウントしてみます。

Python python counter Counter
collections COLLECTIONS LIST
list LIst Dictionary {DICTIONARY}
TUPLE tuple tuple counter {COUNTER}
Set, python, PYTHON, python

input.txtの中に現れる単語を読み込んでカウントをとる場合には、Counterを使用して以下のように実装できます。

import collections
import re

with open("input.txt", "r", encoding="UTF-8") as f:
    words = re.findall(r"\w+", f.read().lower())

print(f"words = {words}")

print("=====")
counter = collections.Counter(words)
print(counter)
print(counter.most_common(3))
【実行結果】
words = ['python', 'python', 'counter', 'counter', 'collections', 'collections', 'list', 'list', 'list', 'dictionary', 'dictionary', 'tuple', 'tuple', 'tuple', 'counter', 'counter', 'set', 'python', 'python', 'python']
=====
Counter({'python': 5, 'counter': 4, 'list': 3, 'tuple': 3, 'collections': 2, 'dictionary': 2, 'set': 1})
[('python', 5), ('counter', 4), ('list', 3)]

上記例では、正規表現のreモジュールを使用しています。reモジュールの使い方は「正規表現モジュール re の基本的な使い方」にまとめていますので参考にしてください。

正規表現は一定パターンに一致するものを抽出できるもので、この例では読み込んだ文字列をlower()で小文字にしてから単語リストを作成しています。

正規表現の抽出結果はリストになっているので、Counterに渡してインスタンス化します。後は上記で見てきたメソッド等を同様に使うことができます。

このようにすることでCounterを使ってテキストファイル中の単語数を簡単にカウントすることが可能です。

まとめ

リストの要素数をカウントする際に利用できるcollectionsモジュールのCounterについて解説しました。

この記事では、Counterの基本的な使い方の説明とファイル内の単語をカウントする例を紹介しました。collectionsモジュールのCounterは、便利なメソッドが多く用意されているため、是非要素数をカウントする際には使用してみてください。

Note

Counterの公式ドキュメントの記載はこちらを参照してください。