はじめに
こんにちは!AI開発事業部の須藤です。
この記事は、Advent Calendar 2022の21日目の記事になります。
主に画像系のアプリ開発に携わっておりますが、分析業務なども経験してきました。
この記事はpandasのテーブル検索における3つの手法とそれぞれの処理速度を比較していきたいと思います。
検証環境
- MacBook Pro (13-inch, M1, 2020)
- Python 3.8.12
- pandas 1.4.0
- numpy 1.22.2
データを用意する
今回は日本郵便株式会社さんが公開している郵便番号のCSVデータを使わせていただきます。
以下のリンクからデータを取得できます。
https://www.post.japanpost.jp/zipcode/dl/roman-zip.html
検証開始
データを読み込みます。
import pandas as pd
names = [
"郵便番号", "都道府県名", "市区町村名", "町域名",
"都道府県名(ローマ字)", "市区町村名(ローマ字)", "町域名(ローマ字)"
]
tbl = pd.read_csv(
"./KEN_ALL_ROME.csv", encoding="cp932", header=None, names=names, dtype={"郵便番号": str})
テーブルの中身は以下のようになっていて、全部で124,541レコードありました。
それではこちらのテーブルを使って、都道府県別にデータを抽出した場合の速度比較をしていきます。
検索方法は3つ用意しました
- 比較演算子を使うノーマルな検索
例tbl[tbl["都道府県名"]=="北海道"]
- queryメソッドを使った検索
例tbl.query("都道府県名=='北海道'")
- indexを使った検索
例tbl2 = tbl.set_index("都道府県名").sort_index()
tbl2.loc["北海道"]
検証コードです。
import timeit
areas = tbl["都道府県名"].unique()
def func():
""" 比較演算子を使うノーマルな検索 """
for area in areas:
sub = tbl[tbl["都道府県名"]==area]
def func_query():
""" queryメソッドを使った検索 """
for area in areas:
sub = tbl.query("都道府県名==@area")
tbl2 = tbl.set_index("都道府県名").sort_index()
def func_index():
""" indexを使った検索 """
for area in areas:
sub = tbl2.loc[area]
run_time = timeit.timeit("func()", number=10, setup='from __main__ import func')
print(f"func = {run_time} sec")
run_time = timeit.timeit("func_query()", number=10, setup='from __main__ import func_query')
print(f"func_query = {run_time} sec")
run_time = timeit.timeit("func_index()", number=10, setup='from __main__ import func_index')
print(f"func_index = {run_time} sec")
3つの手法に対し、timeitモジュールで、それぞれ10回ずつ実行した合計時間を表示します。
結果はこのようになりました。
func = 1.9060642909999927 sec
func_query = 0.7746682920000012 sec
func_index = 0.021593332999998438 sec
indexを使った検索が一番速く、ノーマルな手法に対しおよそ88倍という結果になりました。
indexを使った手法は事前に都道府県名をindexにセットしソートしておりますが、それを差し引いても十分すぎるほど速いです。
おわりに
いかがでしたでしょうか?
本編で触れませんでしたが、個人的にはqueryがノーマルの3倍近い検索速度だったのが驚きでした。
今回はシンプルな検索条件で検証しましたが、ケースバイケースで色んな手法を使い分けていただければと思います。
本記事が少しでも参考になれば幸いです。
最後まで呼んでいただき、ありがとうございました!