DataFrameの2列の値からdictを作る

DataFrameの2列の値のうち、一方の列の値をKey、もう一方の列のValueとする辞書を作る方法の紹介です。
自分はよくやるのですが、意外に知られてないらしいことと、なぜこれが動くのか自分も十分に理解していなかったのでこの機会に調べました。

例えば次のようなデータフレームがあったとします。

id col1 col2
1 key1 value1
2 key2 value2
3 key3 value3
4 key4 value4
5 key5 value5

そして、このcol1の値をkey, col2の値をvalueとして、
{‘key1’: ‘value1’, ‘key2’: ‘value2’, ‘key3’: ‘value3’, ‘key4’: ‘value4’, ‘key5’: ‘value5’}
のようなdictを作りたいとします。

このような場合、僕は次のコードのようにデータフレームの該当の2列を抽出して、そのvaluesプロパティをdict関数に渡します。


import pandas as pd
# サンプルとなるデータフレームを作る
data = [[i, "key"+str(i), "value"+str(i)] for i in range(1, 6)]
df = pd.DataFrame(data, columns=["id", "col1", "col2"])

result_dict = dict(df[["col1", "col2"]].values)
print(result_dict)
# {'key1': 'value1', 'key2': 'value2', 'key3': 'value3', 'key4': 'value4', 'key5': 'value5'}

注意ですが .values を忘れると次のように 列名:Seriesの辞書になってしまいます。


print(dict(df[["col1", "col2"]]))
"""
{'col1': 0    key1
1    key2
2    key3
3    key4
4    key5
Name: col1, dtype: object, 'col2': 0    value1
1    value2
2    value3
3    value4
4    value5
Name: col2, dtype: object}
"""

これも参考ですがよく見かけるのは次ような書き方。


result_dict = dict()
for i in range(len(df)):
    result_dict[df.iloc[i]["col1"]] = df.iloc[i]["col2"]

print(result_dict)
# {'key1': 'value1', 'key2': 'value2', 'key3': 'value3', 'key4': 'value4', 'key5': 'value5'}

さて、話を戻してdict(df[["col1", "col2"]].values)がなぜうまく動くのかです。

改めてドキュメントを読んでみるとdictはiterableを引数に取ることができます。
class dict(iterable, **kwarg)
そして、
iterable のそれぞれの要素自身は、ちょうど 2 個のオブジェクトを持つイテラブルでなければなりません。
とのことです。

実際見てみると、df[[“col1”, “col2”]].valuesはその条件を満たすデータになっています。


print(df[["col1", "col2"]].values)
"""
[['key1' 'value1']
 ['key2' 'value2']
 ['key3' 'value3']
 ['key4' 'value4']
 ['key5' 'value5']]
"""

DataFrame側にdictに渡したら空気を読んでいい感じに変換される機能が実装されている、と勘違いしていたこともあるのですが、
dictの通常の挙動にマッチした動きだったようです。
for分で回すのに比べてかなりスマートに書けるので、最初に紹介した書き方は結構おすすめです。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です