Pandasのappendが遅すぎる時の対処法
Pandasのappendは遅い、遅すぎる...........
とある処理を行っていて、処理後の行をpandasのDataFrameに対してappendしていく場面が結構あると思います。
行数が数万ぐらいのデータであれば、appendを使っても特に困ることはないと思うのですが(それならappend便利)、数千万行のデータになるとappendの遅さが顕著になります。
appendは非破壊的な動作をするので、元のDataFrameを変化させません。つまり...
df = pd.DataFrame() df = df.append(row)
のようにいちいち元のDataFrameに代入する必要があるわけです。
このとき、appendによって元のDataFrameのコピーが作成されるわけで、元のDataFrameのサイズが大きくなるほどコピーに時間がかかり非効率になります。
進捗バーを表示させると最初は早いけど後半遅い現象の原因です。
普通はこの場合、ファイル出力等をして対処すると思いますが、今回は違ったアプローチをとりました。
使ったのはコレ↓
pandas.DataFrame.from_dict — pandas 0.22.0 documentation
辞書型のデータからDataFrameを作成する関数 from_dict()
使い方は以下のようになります。
dic = {'index_1':[1,2,3], 'index_2':[4,5,6], 'index_3':[7,8,9]} df = pd.DataFrame() df = df.from_dict(dic, orient='index') #カラム名の設定 df.columns = ['col1', 'col2', 'col3']
orientで辞書型のkeyをどう処理するかが変わります。
orient = 'columns' で辞書のkeyがcolumnに相当するような読み込み
orient = 'index' で辞書のkeyがindexに相当するような読み込み
が出来ます。今回は1行ごとの処理なのでindexを選択
速度の比較としては
最終サイズのDataFrameを作成。locで行ごとに代入 - 12it / s
辞書型に挿入、最後にfrom_dict - 13000it /s
辞書型の方はただの挿入なのでクソ早いです、1000倍
ちなみにappendは平均とかだそうと思ったけど面倒なのでやめました。
メモリに乗り切ればこの方法は有用ですね。
他に方法があればぜひ教えてください!