🐍

Pythonで辞書のリストの平均を取る

2022/12/14に公開

辞書のリストの平均をキーごとに取得するのは結構めんどう、なので簡単に使える関数を書いてみた。

def dict_average(dicts: Iterable[Dict]) -> Dict:
    dicts: List[Dict] = list(dicts)
    averaged = {}

    for k, v in dicts[0].items():
        try:
            v = v.item()
        except:
            pass
        if type(v) in [int, float]:
            averaged[k] = v / len(dicts)
        else:
            averaged[k] = [v]

    for d in dicts[1:]:
        for k, v in d.items():
            try:
                v = v.item()
            except:
                pass
            if type(v) in [int, float]:
                averaged[k] += v / len(dicts)
            else:
                averaged[k].append(v)

    return averaged

各辞書オブジェクトの値について、キーごとにPythonのint型とfloat型は平均を取るようにして、それ以外の型はリストに押し込むようにしている。

注意点として、numpyやPyTorchの数値型はPythonのプリミティブではないので、int型およびfloat型かどうかで分岐をすると数値の平均を取ることができない。
その対策として、numpyとPyTorchの数値型は.item()メソッドによってPythonのプリミティブに変換することができるので、tryしてPythonのプリミティブ型に変換するようにしている。

動作例は以下のようになる。

dict_list = [
	{"a": 3, "b": "hoge"},
	{"a": 2, "b": "fuga"},
]

print(dict_average(dict_list))

# {
#	'a': 2.5,
#	'b': ['hoge', 'fuga'],
# }

改善案があればぜひコメントへ!

Discussion