内容について
pythonを使用している皆様
データ処理をする際、pandasを使用していますか?
ちょっとしたデータを弄るときはそれほど気にはしませんが、ビッグデータを扱うときに
「早く処理終わってくんねーかなー」
「無限ループ入ったわ」
みたいなことありませんか?
私はあります。実際に40分くらいかけて読み込んだこともあります。
そんな皆様にpandasを使用したコードに一言追加するだけで爆速になる方法を紹介します(多分知ってると思いますが……)。
それは
swifterを追加しよう!!!
です。
では、具体的にどのくらい読み込み速度が違うのか見ていきましょう。
検証
pandasよりもデータ処理速度が優れているpolarsというライブラリがありますが、pandasに慣れている人からすると手を付けづらい部分もあるのではないかと思います。
しかし、swifterはpandasのコードに、そっと左手を添えるかのように追加するだけです。
では見ていきましょう。
まずはswifterをインストールしましょう。
$ pip install swifter
こちらでインストールの方法等書いていますが、私は上記のコマンドしか実行していませんが問題ありませんでした。
次に必要なライブラリをインポートしましょう。
import pandas as pd
import numpy as np
import swifter
import time
今回はpandasとswifterの比較を行いますが、ここで1つ注意点
swifterを使用する際は、pandasもインポートすること
先ほども言いましたが、そっと左手を添えるのです。
ボール(データ)があっても、シュートを打つための右手(pandas)がないと処理は実行できません。
忘れずにインポートしましょう。
また、処理速度を比較するためにtimeもインポートしておきます。
では、比較するためのデータを作成しましょう。
# インデックスとカラムの数を決める
rows = 10**7
cols = 5
# ランダムな整数型でデータ作成
data = np.random.randint(
low=np.iinfo(np.int32).min,
high=np.iinfo(np.int32).max,
size=(rows,cols)
)
df = pd.DataFrame(data,columns=[f'col{i+1}'.format(i) for i in range(cols)])
df.to_csv('time_data.csv')
上記コードを実行することで、1000万行×5列のcsvファイルを作成します。
このcsvファイル、なんと623MBもあります。
ではこのファイルを読み込んでいきましょう。
pandas_df = pd.read_csv('time_data.csv',encoding='utf-8')
(。´・ω・)ん?
swifter使わねーの?と思ったそこのあなた。
残念なことに
swifterはデータの読み込みはできない。
というデメリットがございます。
あくまで、データはpandasで読み込む必要があるみたいです。
バージョンが更新されて読み込めるようになるといいですね!
では、データを処理して比較していきます。
今回は2通りの処理を行い、それぞれでどの程度処理速度に違いがあるかを見ていきます。
- データフレームのすべての要素に対して1を足す。
- データフレームのすべての要素の平方根を取る。
特定のカラムに対して処理を行うのではなく、すべての要素に対して処理を行うことで負担をかけてやろうと思います。
# すべての要素に対して1を足す
# pandas
pd_start_time = time.time()
pd_1 = pandas_df.applymap(lambda s : s+1)
pd_end_time = time.time()
# swifter
swift_start_time = time.time()
swi_1 = pandas_df.swifter.applymap(lambda s : s+1)
swift_end_time = time.time()
# すべての要素に対して平方根を取る
# pandas
pd_start_time = time.time()
pd_sqrt = pandas_df.applymap(np.sqrt)
pd_end_time = time.time()
# swifter
swift_start_time = time.time()
swi_sqrt = pandas_df.swifter.applymap(np.sqrt)
swift_end_time = time.time()
print(f'pandas:{pd_end_time-pd_start_time}')
print(f'swifter:{swift_end_time-swift_start_time}')
すべての要素に対して1を足す
pandas:16.809720754623413
swifter:0.09489941596984863
すべての要素に対して平方根を取る
pandas:88.26044082641602
swifter:25.88457489013672
圧勝ですね。
めちゃくちゃ早いです。
僕の上司が誰も見ていない間に大量にお菓子を取っていき引き出しにしまう速さ並みに早いです。
しかも、追加したコードは「.swifter」のみ。
pandasしか使ったことない人でも、余裕で使えますね!
polarsに慣れないなぁ。けど、処理速度早くしたいなぁ。という人は是非使ってみてください!
終わりに
今回はpandasに左手を添えました。
私自身も最近発見して練習しているところですので、もしかしたら対応していない処理もあるかもしれません。
また、他の処理では書き方が違うかもしれません。
そのようなことがありましたら、教えていただけると助かります。
また、勉強して有益な情報があれば共有します。
それでは!!!