Pythonで辞書の値の最大値・最小値とそのキーを取得

Pythonで辞書(dict型オブジェクト)の値valueの最大値・最小値およびそのキーkeyを取得する方法を説明します。 例として以下の辞書を使います。

d = {'a': 100, 'b': 20, 'c': 50, 'd': 100, 'e': 80}

内容は以下の通り。

辞書のキーkeyの最大値・最小値を取得 辞書の値valueの最大値・最小値を取得 辞書の値が最大・最小となるキーを取得 辞書の値が最大・最小となるキーと値を同時に取得 最大・最小となる値が複数存在する場合 pandas.Seriesに変換して処理

辞書のキー(key)の最大値・最小値を取得

イテラブルオブジェクトの最大の要素を返す関数max()に辞書オブジェクトを渡すと、キーkeyの最大値が返ってきます。文字列の場合はアルファベット順の最後の値となります。

max_d = max(d)
print(max_d)
# e

これは、辞書のイテレーターは要素のキーを列挙するため。 min()でも同じ。

min_d = min(d)
print(min_d)
# a

辞書の値(value)の最大値・最小値を取得

辞書のvalues()メソッドは辞書の値valueのビューを返します。

これをmax()に渡すと、辞書の値の最大値が取得できます。

max_v = max(d.values())
print(max_v)
# 100

min()でも同じ。

min_v = min(d.values())
print(min_v)
# 20

辞書の値が最大・最小となるキーを取得

辞書の値が最大・最小となるキーは以下のように取得できます。

max_k = max(d, key=d.get)
print(max_k)
# a

min_k = min(d, key=d.get)
print(min_k)
# b

max(), min()の引数keyには、各要素が比較される前にリストの各要素に適用される関数(呼び出し可能オブジェクト)を指定します。これにより、各要素そのものではなく引数keyに指定した関数の結果を比較して最大値・最小値が算出されます。 ここでは引数keyに辞書のget()メソッドを指定しています。get()は辞書のキーを渡してその値を返すメソッド。

上述のように辞書のイテレーターは要素のキーkeyを列挙します。そのキーを引数としてget()メソッドを適用することで値valueが返され、それに従って最大値・最小値が算出されます。

辞書の値が最大・最小となるキーと値を同時に取得

辞書の値が最大・最小となるキーと値を同時に取得したい場合は、辞書のitems()メソッドを使います。items()メソッドは辞書のキーと値のタプル(key, value)のビューを返します。 max(), min()の引数keyにタプルの2要素目(= 値value)を取得する無名関数を指定すると、値valueに従って最大値・最小値が求められます。 無名関数(ラムダ式)については

max_kv = max(d.items(), key=lambda x: x[1])
print(max_kv)
# ('a', 100)

print(type(max_kv))
# <class 'tuple'>

タプルのアンパックを利用して、それぞれ別々の変数に代入することもできます。

max_k, max_v = max(d.items(), key=lambda x: x[1])
print(max_k)
# a

print(max_v)
# 100

最小値min()でも同じです。

min_kv = min(d.items(), key=lambda x: x[1])
print(min_kv)
# ('b', 20)

最大・最小となる値が複数存在する場合

これまでの例では、最大・最小となる値valueが複数存在する場合、その中のどれか一つのキーkeyまたはキーと値のタプルが返されていた。 リスト内包表記を使うことで、最大・最小となる値valueが複数存在する場合、そのキーまたはキーと値のタプルをリストとして取得できます。

キーと値のタプルを取得する例を示します。

max_kv_list = [kv for kv in d.items() if kv[1] == max(d.values())]
print(max_kv_list)
# [('a', 100), ('d', 100)]

キーのみのリストを取得する例を示します。

max_k_list = [kv[0] for kv in d.items() if kv[1] == max(d.values())]
print(max_k_list)
# ['a', 'd']

この方法だと、最大・最小となる値valueが一つだけの場合も要素数が1のリストが取得できます。

min_kv_list = [kv for kv in d.items() if kv[1] == min(d.values())]
print(min_kv_list)
# [('b', 20)]

pandas.Seriesに変換して処理

辞書をpandas.Seriesに変換してから処理することもできます。 コンストラクタpd.Series()に辞書を指定するとキーがindex、値がvaluesのpandas.Sereisが生成されます。

import pandas as pd

d = {'a': 100, 'b': 20, 'c': 50, 'd': 100, 'e': 80}

s = pd.Series(d)

print(s)
# a    100
# b     20
# c     50
# d    100
# e     80
# dtype: int64

print(s.index)
# Index(['a', 'b', 'c', 'd', 'e'], dtype='object')

print(s.values)
# [100  20  50 100  80]

辞書の値(value)の最大値・最小値を取得

pandas.Seriesのメソッドmax(), min()で元の辞書の値valueの最大値・最小値を取得できます。組み込み関数max(), min()を使います。

print(s.max())
# 100

print(s.min())
# 20

辞書のキー(key)の最大値・最小値を取得

pandas.Seriesのindexの最大値・最小値が元の辞書のキーkeyの最大値・最小値となります。

print(max(s.index))
# e

print(min(s.index))
# a

辞書の値が最大・最小となるキーを取得

pandas.Seriesのメソッドidxmax(), idxmin()で元の辞書の値が最大・最小となるキーを取得できます。最大値・最小値が複数ある場合は最初のキーのみが返されます。

print(s.idxmax())
# a

print(s.idxmin())
# b

最大値・最小値が複数ある場合にすべてのキーを取得したい場合は、最大値・最小値に等しい要素をブールインデックス参照で抽出し、index属性を取得します。

print(s[s == s.max()])
# a    100
# d    100
# dtype: int64

print(s[s == s.max()].index)
# Index(['a', 'd'], dtype='object')

リスト型にしたい場合はIndexのtolist()メソッドかlist()を使います。

print(s[s == s.max()].index.tolist())
# ['a', 'd']

print(list(s[s == s.max()].index))
# ['a', 'd']

最小値の場合も同じです。この方法の場合、該当するキーが一つだけの場合もIndexやリストで返されます。

print(s[s == s.min()])
# b    20
# dtype: int64

print(s[s == s.min()].index)
# Index(['b'], dtype='object')

print(s[s == s.min()].index.tolist())
# ['b']

print(list(s[s == s.min()].index))
# ['b']

その他の処理

辞書をpandas.Seriesに変換すると、ソートや条件抽出などをするのも簡単で便利です。

print(s.sort_values())
# b     20
# c     50
# e     80
# a    100
# d    100
# dtype: int64

print(s[s > 60])
# a    100
# d    100
# e     80
# dtype: int64
Last Updated: 6/26/2019, 10:34:03 PM