📗

Pythonの 辞書データの結合をいろいろ試した

2022/03/13に公開

TFX のサンプルコードを読んでいたら辞書データの処理で詰まったのでまとめてみました。

コードはこちら

内包表現

次のように、list の中身をkeyにし、keyのサイズをvalueにする、という使い方ができます。

dic1 = {
            category:len(category)
                for category in ['banana', 'apple', 'strawberry']
}

結合処理

さきほどの dic1 に結合させる dic2 を作ります。

dic2 = {'orange':100}

アスタリスク

下記のように、アスタリスクを2つつけた辞書データを {} でかこって結合します。

{**dic1, **dic2}

出力:
{'banana': 6, 'apple': 5, 'strawberry': 10, 'orange': 100}

なお、出力は以降全て同じです。

それはそうかという感じですが、結合する辞書を変数ではなく直接書く場合はアスタリスクいらないようです。

{**dic1, 'orange':100}

出力:
{'banana': 6, 'apple': 5, 'strawberry': 10, 'orange': 100}

update

update メソッドを使って辞書を追加します。

import copy

dic3 = copy.copy(dic1)

dic3.update(dic2)

出力:
{'banana': 6, 'apple': 5, 'strawberry': 10, 'orange': 100}

マージ演算子(Python3.9から)

Python3.9からはマージ演算子 | を使えるようです。

dic1 | dic2

出力:
{'banana': 6, 'apple': 5, 'strawberry': 10, 'orange': 100}

処理速度の比較

それぞれの処理速度を比較してみます。

Pandas の DataFrame ファイルに to_dict() メソッドを使って大規模な辞書を作成してみます。

比較的大きなデータセットということで、sales_train_validation.csvを使ってみます。

そのまま使うとカラムが多すぎたせいか処理に時間がかかったので、カラム数を200に絞りました。

import pandas as pd
import time

df = pd.read_csv("sales_train_validation.csv")
df = df.iloc[:, :200]

これで 行数 30490 x カラム数 200 のデータができました。

単純に to_dict()メソッドで吐き出されるデータを使うと、key が index番号で全てのカラムの key が被って上書きされてしまうので、カラム名+index番号 を key になるようにします。

import time
start = time.time()

dic4 = {}

for column in df.columns:
    
    dic_tmp = {column+str(k):v for k,v in df[column].to_dict().items()}
    
    dic4 = # それぞれの結合処理を入れる
    
print(f"elapsed_time:{round((time.time() - start), 1)}[sec]")

比較したところ、update 使うのが早いようです。

結合処理 処理速度
アスタリスク 35.1秒
update 2.7秒
マージ演算子 7.5秒

以上になります、最後までお読みいただきありがとうございました。

参考サイト

https://blog.utgw.net/entry/2017/08/04/013507

https://blog.utgw.net/entry/2017/08/04/013507

https://www.python.jp/pages/python3.9.html#辞書のマージ演算子

https://www.kaggle.com/c/m5-forecasting-accuracy

Discussion