医療職からデータサイエンティストへ

統計学、機械学習に関する記事をまとめています。

”pd.mearge”はもう遅い、Python"join"で高速データ結合

pythonでデータフレーム結合

Pythonである値をkeyにデータを結合をしたいとき、pandasのmergeが使えますが、データの行数が膨大だと実行に時間がかかります。

www.medi-08-data-06.work

そんなときには、joinを使うことで、データ結合の処理速度を上げることができます。

joinを使って

実際にやってみましょう。まずは架空のデータセットを作ります。あるときのお店の売り上げデータ(100行)と、そのお店の社長名を格納したマスターデータです。

import numpy as np
import pandas as pd
import random
# お店データを作成
np.random.seed(123)

# 架空のデータ作成
store_id = ['A', 'B', 'C', 'D', 'E', 'F', 'G']
store = random.choices(store_id, k=100)
sales = [random.randint(100, 1000) for i in range(100)]

ceo = ['Yamada', 'Tanaka', 'Kato', 'Yamamoto', 'Sato', 'Mori', 'Kanayama']

store_data = pd.DataFrame({'store': store,
                           'sales': sales})
ceo_data = pd.DataFrame({'store': store_id,
                         'ceo': ceo})

store_data

store sales
E 789
G 181
D 667
... ...
A 676
A 571

ceo_data

store ceo
A Yamada
B Tanaka
C Kato
D Yamamoto
E Sato
F Mori
G Kanayama

目的はこのstore_dataに、店舗名をkeyにして社長名を結合することです。 王道のmergeを使った書き方では、このようになります。実行時間も計測しておきましょう。jupyter notebookであれば、%timeitを使うことで、複数回実行した場合の平均的な実行時間を計測してくれます。

Jupyter Notebookでセルの実行時間をはかるなら%%timeを使おうって話 - EnsekiTT Blog

# pd.marge
%timeit pd.merge(store_data, ceo_data, how='left', on='store')

>975 µs ± 10.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

続いてjoinです。joinは結合する左側テーブルのkeyはon句で指定し、右側はindexがkeyになります。

# join
%timeit store_data.join(ceo_data.set_index('store'), how='left', on='store')

>664 µs ± 467 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)

pandasのmergeが975usに対して、joinでは664usとなりました。しかも、mergeの速度のばらつきが10.4usであるのに対して、joinでは467nsと、安定した速度で結合できていますね!

mergejoinはどちらを使うべきか

個人的には、通常はjoinの方が速度が速く、メソッドチェーンで複数繋ぐことができるので、joinを使っていきたいです。ただ、結合のkeyが複数になった場合は、可読性からもmergeを使った方が良いかもしれないです。

その他、joinmergeの挙動の違いや、使い分けなどご意見ありましたら、是非ともコメントいただけると幸いです!

※本記事は筆者が個人的に学んだこと感じたことをまとめたブログになります。所属する組織の意見・見解とは無関係です。

参考

pandas.DataFrameを結合するmerge, join(列・インデックス基準) | note.nkmk.me