Pythonである値をkeyにデータを結合をしたいとき、pandasのmerge
が使えますが、データの行数が膨大だと実行に時間がかかります。
そんなときには、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と、安定した速度で結合できていますね!
merge
とjoin
はどちらを使うべきか
個人的には、通常はjoin
の方が速度が速く、メソッドチェーンで複数繋ぐことができるので、join
を使っていきたいです。ただ、結合のkeyが複数になった場合は、可読性からもmerge
を使った方が良いかもしれないです。
その他、join
とmerge
の挙動の違いや、使い分けなどご意見ありましたら、是非ともコメントいただけると幸いです!
※本記事は筆者が個人的に学んだこと感じたことをまとめたブログになります。所属する組織の意見・見解とは無関係です。