私のプログラムは、巨大なパンダデータフレームから列の値に基づいて行をフェッチする必要があります。応答時間は重要です。私はそれを行うために最も一般的な方法を使用します、例えば:
df.loc[df['id'] == 500000, :]
パーtimeit
私のMac上のそれは100万行のデータフレーム上で上記の操作を完了するために4ミリ秒を要しました。しかし、私の目標は、時間を0.4ミリ秒に短縮することです。私はかつてこのデータフレームをセットに変換することを検討しましたが、セットは順序付けられておらず、インデックス作成やスライスをネイティブにサポートしていません。助言がありますか?
これを設定しましょう:
import pandas as pd
import numpy as np
df = pd.DataFrame({"id": np.random.randint(100,size=(1000000,))})
次に、いくつかのオプションのベンチマークを行いましょう。現在のブール値+ .loc
:
>>> timeit.timeit("df.loc[df['id'] == 50, :]", setup = "from __main__ import df", number=1000)
2.566220869999597
クエリエンジン:
>>> timeit.timeit("df.query('id == 50')", setup = "from __main__ import df", number=1000)
14.591400260000228
インデックスを個別のルックアップとして使用する:
>>> idx = pd.Index(df['id'])
>>> timeit.timeit("df.loc[idx == 50, :]", setup = "from __main__ import df, idx", number=1000)
2.2155187300013495
ルックアップにデータフレームインデックスを使用する:
>>> df.index = df["id"]
>>> timeit.timeit("df.loc[50, :]", setup = "from __main__ import df", number=1000)
2.625610274999417
そして.isin()
、コメントの誰かが持っていたその考え:
>>> timeit.timeit("df.loc[df['id'].isin([50]), :]", setup = "from __main__ import df", number=1000)
9.542700138999862
クエリエンジンが(予想どおり)単純な同等性のために遅いことを除いて、あなたが持っているルックアップ時間よりもはるかに良くなることはないように見えます。
df_unique = pd.DataFrame({'id': range(1000000)})
一意のIDがどのように役立つかを見てみましょう。
>>> timeit.timeit("df_unique.loc[df_unique['id'] == 50, :]", setup = "from __main__ import df_unique", number=1000)
1.9672015519990964
それから口述に:
>>> df_unique.index = df_unique['id']
>>> df_dict = df_unique.to_dict(orient='index')
>>> timeit.timeit("df_dict[50]", setup = "from __main__ import df_dict", number=1000)
6.247700002859347e-05
まあ、これは明らかに勝者のようです。
>>> timeit.timeit("pd.Series(df_dict[50])", setup = "from __main__ import df_dict, pd", number=1000)
0.2747819870000967
何かのためにシリーズにキャストバックする必要がある場合でも、これは以前よりも桁違いに高速です。(必要に応じて、シリーズをdictに非常に簡単にマップし直し、オーバーヘッドなしでdictルックアップの速度を維持することもできます)
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加