Pythonのコードに慣れてきたら、処理時間が気になってきます。
Jupyter labやColabを使っている場合はマジックコマンドで簡単に処理時間を計測することができます。
マジックコマンドで処理時間を測定する場合はtimeやtimeitをimportする必要がありません。
%%timeの使い方
セル内のコードの処理時間を測る場合は、 「%%time」 をセルの先頭に記述するだけです。
次の例は売上集計データをPandasの pd.read_excel() で読み込んだデータ sales から1行ずつループして金額が50万以上のものをresultで定義した空のリストにappenndするコードです。
このデータはわずか30行ほどのものです。
ところで、Pandasでこのようなループはあまりお勧めしないやり方です。
理由は実行速度が遅いからです。
JupyterLabのマジックコマンド 「%%time」 を使うことで、Pandasの苦手なループ処理と、Pandasが得意な条件抽出する方法でどれくらい時間の差があるか確認したコードです。(Colabでも使用可能)
まずはExcelデータの読み込みコード(csvデータの場合、read_csv()を使う)
import pandas as pd sales = pd.read_excel('./data/売上データ_練習用.xlsx', sheet_name=0)
ループ文で1行づつデータを条件判定するコード
%%time result = [] for _,v in sales.iterrows(): if v['金額'] > 500000: result.append(v)
結果
CPU times: user 11.2 ms, sys: 796 µs, total: 12 ms
Wall time: 13.9 ms
結果は、処理時間は13.9 msでした。
次は条件抽出するコード
%%time result = sales[sales['金額'] > 500000]
結果
CPU times: user 4.96 ms, sys: 303 µs, total: 5.26 ms
Wall time: 5.64 ms
こちらの結果は処理時間は5.64 msで最初の方法に比べると約半分です。
ちなみに、結果に表示される意味ですが次のとおりです。
- user: ユーザースペースで CPU が利用された時間
- sys: カーネルスペースで CPU が利用された時間
- total: CPU が利用された時間の合計 (total = user + sys)
- Wall time: 全体の実行時間
%%timeitの使い方
timeitは処理時間の計測を単純に測るだけではなく、同じ処理をループさせたものを複数回実行するものです。
nはループ数
rは繰り返し数
この場合、10000回同じ処理を行った時間を7回測って平均処理時間を返すということです。
結果は平均と標準偏差が算出されます。
%%time で試したものと同じコードで試してみます。
ループ処理する場合
%%timeit -r 7 -n 10000 result = [] for _,v in sales.iterrows(): if v['金額'] > 500000: result.append(v)
結果
2.43 ms ± 129 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
条件処理で抽出する場合
%%timeit -r 7 -n 10000 result = sales[sales1['金額'] > 500000]
結果
369 µs ± 3.7 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
圧倒的な差が出ていることがわかります。
尚、明示的にループ回数「-n」と処理回数「-r」オプションを決めない場合は自動で「-n」と「-r」オプションの値が決まります。
%timeと%timeitの使い方
%記号が一つの場合は1行だけの処理時間を測定します。
%timeや%timeitのすぐ横に1行のコードを書くのがポイントです。
以下簡単な例です。
%timeit [x ** 2 for x in range(10000)]
結果
100 loops, best of 5: 2.38 ms per loop
%time [x ** 2 for x in range(10000)]
結果
CPU times: user 2.84 ms, sys: 0 ns, total: 2.84 ms
Wall time: 2.86 ms