HOWTO · Python

Python リストで一意の値を数える

Python のリストで一意の値を数える

このページの内容

Python のリストで一意な値を数える簡単な方法は len(set(values)) です。リストの要素がハッシュ可能であれば使えます。数値、文字列、すべての要素がハッシュ可能なタプルが該当します。各値の出現回数も知りたい場合は、collections.Counter を使うと、一度の処理で一意な値の数と値ごとの出現頻度を求められます。データがすでに NumPy 配列に格納されているなら、numpy.unique が適しています。この記事では、3つの方法と選び方を説明します。

set() で一意な値を数える

組み込みの set() 関数は、リストをセットに変換します。セットには異なる値がそれぞれ1つずつ格納されます。結果を len() に渡せば、追加のインポートなしで一意な値の数を求められます。

次の例を実行します。このセクションのコードと出力は正準版のままです。表示ラベルがある場合も英語のままです。

values = [1, 2, 2, 3, 4, 4, 5]
unique_values = set(values)

print(len(unique_values))

出力:

5

set(values) は重複している 2 と 4 を取り除き、len() は残った要素の数を返します。入力の要素はハッシュ可能でなければなりません。リストや辞書などを要素として含むリストを渡すと、Python は TypeError を発生させます。また、セットは元のリストの順序を保持しないため、「いくつあるか」は分かっても、「どの値が先に現れたか」は分かりません。一意な値を最初に現れた順に取得するには、代わりに list(dict.fromkeys(values)) を使います。その長さも同じ一意な値の数になります。

collections.Counter で一意な値を数える

collections.Counter は、イテラブル内の各要素の出現回数を数える辞書のようなクラスです。一意な値の数と各値の出現頻度を同時に知りたい場合に適しています。

このセクションのコードと出力は正準版のままです。サンプル文字列や表示ラベルは英語のままです。

from collections import Counter

values = ["apple", "banana", "apple", "orange", "banana", "kiwi"]
counter = Counter(values)

print(len(counter))
print(dict(counter))

出力:

4
{'apple': 2, 'banana': 2, 'orange': 1, 'kiwi': 1}

counter は各値とその出現頻度を対応付けるため、len(counter) はこのリストにある異なるキーの数、つまり4を返します。counter["apple"] のようにインデックスで指定すると、特定の値の出現頻度を取得できます。また、counter.most_common(1) は最も頻繁に出現する要素を返します。set() と同様に、collections.Counter はハッシュ可能な要素を扱い、標準ライブラリに含まれています。

NumPy で一意な値を数える

NumPy はサードパーティ製パッケージです(pip install numpy でインストールできます)。その numpy.unique 関数は、配列のような入力からソート済みの一意な値を返します。返された結果のサイズが一意な値の数です。return_counts=True を渡すと、各値の出現頻度も取得できます。

このセクションのコードと出力は正準版のままです。表示ラベルがある場合も英語のままです。

import numpy as np

values = np.array([1, 2, 2, 3, 4, 4, 5])
unique_values, counts = np.unique(values, return_counts=True)

print(len(unique_values))
for value, count in zip(unique_values, counts):
    print(value, count)

出力:

5
1 1
2 2
3 1
4 2
5 1

ここでは unique_values にソートされた5つの異なる数値が格納され、counts には各数値の出現回数が格納されます。2 と 4 はそれぞれ2回出現しています。numpy.unique は結果をソートするため、一意な値を順番に取得したい場合にも適しています。データがすでに NumPy 配列にある場合や、すでに NumPy を利用している場合に選びましょう。通常の Python リストなら、set() を使うことで追加の依存を避けられます。

適切な方法を選ぶ

3つの方法はいずれも同じ一意な値の数を返します。入力の種類と、ほかに必要な情報に合わせて選びましょう。

  • ハッシュ可能な要素の一意な値の数だけが必要で、標準ライブラリだけで使える最も簡潔な方法を選びたい場合は、set() を使います。
  • 各値の出現頻度や最頻出の値など、値ごとの集計も必要な場合は、collections.Counter を使います。
  • データがすでに NumPy 配列にある場合や、一意な値をソートして取得したい場合は、numpy.unique を使います。出現頻度も必要なら return_counts=True を指定します。

どの方法にするかは、一意な値の数そのものではなく、出現頻度やソート済みの結果が必要か、追加の依存を避けたいかで決めます。3つの方法で一意な値の数は同じように求められます。