Python Counter.most_common()とは?多い順に取り出す方法
PythonのCounter.most_common()は、出現回数が多い順に要素を取り出すメソッドです。
「一番よく出る単語は?」「アクセスの多いページTOP5は?」といったランキング処理が1行で書けます。
most_common()の基本的な使い方
from collections import Counter
c = Counter("abracadabra")
print(c)
print(c.most_common(3))
実行結果:
Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1})
[('a', 5), ('b', 2), ('r', 2)]
引数に渡した件数だけ、多い順に返ります。中身は(要素, 回数)のタプルです。
引数を省略すると全件返る
from collections import Counter
c = Counter("abracadabra")
print(c.most_common())
実行結果:
[('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)]
全要素が多い順に並びます。「ランキングをすべて表示したい」ときは引数なしで呼びます。
リストの集計に使う
実務でいちばん多い使い方です。
from collections import Counter
votes = ["佐藤", "鈴木", "佐藤", "高橋", "佐藤", "鈴木"]
c = Counter(votes)
print(c)
print(c.most_common(1))
実行結果:
Counter({'佐藤': 3, '鈴木': 2, '高橋': 1})
[('佐藤', 3)]
戻り値はリストである点に注意してください。1位だけが欲しくても、そのままでは使えません。
name, n = c.most_common(1)[0]
print(name, n)
実行結果:
佐藤 3
[0]でリストから1件目のタプルを取り出し、アンパックして名前と回数に分けています。
戻り値の型を確認する
from collections import Counter
c = Counter(["佐藤", "鈴木", "佐藤"])
r = c.most_common(2)
print(type(r), type(r[0]))
実行結果:
<class 'list'> <class 'tuple'>
辞書ではなくリストなので、r["佐藤"]のようなアクセスはできません。辞書が欲しいときはdict(c.most_common(3))と変換します。
同じ回数のときはどう並ぶか
from collections import Counter
c = Counter(["b", "a", "c", "a", "b"])
print(c)
print(c.most_common())
実行結果:
Counter({'b': 2, 'a': 2, 'c': 1})
[('b', 2), ('a', 2), ('c', 1)]
aとbはどちらも2回ですが、bが先に来ています。回数が同じ要素は、最初に現れた順で並びます(アルファベット順ではありません)。
並び順を自分で決めたいときはsorted()を使います。
print(sorted(c.most_common(), key=lambda x: (-x[1], x[0])))
実行結果:
[('a', 2), ('b', 2), ('c', 1)]
回数の降順、同数なら要素名の昇順になりました。
少ない順・最下位を取り出す
most_common()に「少ない順」のオプションはありません。並びを反転させます。
from collections import Counter
c = Counter(["佐藤", "鈴木", "佐藤", "高橋", "佐藤", "鈴木"])
print("少ない順:", c.most_common()[::-1])
print("最下位2件:", c.most_common()[:-3:-1])
実行結果:
少ない順: [('高橋', 1), ('鈴木', 2), ('佐藤', 3)]
最下位2件: [('高橋', 1), ('鈴木', 2)]
[:-3:-1]は「末尾から2件」という意味です。読みにくければc.most_common()[::-1][:2]でも構いません。
件数より大きい数を渡したとき
from collections import Counter
c = Counter(["佐藤", "鈴木", "佐藤", "高橋", "佐藤", "鈴木"])
print(c.most_common(99))
実行結果:
[('佐藤', 3), ('鈴木', 2), ('高橋', 1)]
エラーにはならず、あるだけ返ります。件数が足りるか事前に確認する必要はありません。
単語の出現ランキングを作る
from collections import Counter
text = "python is easy python is fun python is powerful"
wc = Counter(text.split())
for w, n in wc.most_common(3):
print(f"{w}: {n}")
実行結果:
python: 3
is: 3
easy: 1
for w, n in ...と書くと、タプルがそのまま2つの変数に展開されます。アクセスログのURL集計、アンケートの自由記述の頻出語抽出などに、そのまま応用できます。
「最も多い1件」だけが必要なら、統計の最頻値を求める関数もあります。「Python statistics.mode()とは?最頻値を求める方法」を参照してください。
辞書から直接ランキングを作る
すでに集計済みの辞書があるなら、Counter()に渡すだけです。
from collections import Counter
d = {"りんご": 5, "みかん": 12, "ぶどう": 3}
print(Counter(d).most_common())
実行結果:
[('みかん', 12), ('りんご', 5), ('ぶどう', 3)]
sorted()と比べてどうか
同じことはsorted()でも書けます。
print(sorted(c.items(), key=lambda x: x[1], reverse=True))
結果は同じですが、most_common(n)には2つの利点があります。
- 読みやすい:意図が名前で表現されている
- 上位n件なら速い:全体を並べ替えず、内部で
heapqを使う
要素1,000種・10万件のデータで上位3件を取る処理を1,000回繰り返すと、手元の環境ではmost_common(3)が0.057秒、sorted()が0.090秒でした(環境により変わります)。件数を指定するならmost_common()を選んでください。
most_common()のまとめ
most_common(n)は多い順にn件を返す- 戻り値は
(要素, 回数)のタプルのリスト。辞書ではない - 引数を省略すると全件返る
- 1位だけ欲しいときは
most_common(1)[0] - 同数は最初に現れた順。名前順にしたいなら
sorted()で並べ直す - 少ない順は
[::-1]で反転させる - 要素数より大きいnを渡してもエラーにならない



