初めに
Polarsは大規模テーブルデータ処理に強いライブラリとして知られています。同じくテーブルデータに対して使われるPandasよりも大規模データに対して処理が高速です。データサイエンスや機械学習の分野でよく使われています。
そんな優秀なPolarsですが、列指向のメモリフォーマットを使用し、効率的なデータ処理を可能にするApache Arrowというものが組み込まれているので、テーブルデータではなく行列の列同士の計算に対しても高速になるのではないかと考え、実験してみました。
実験
今回は行が超長い行列の列同士の和をnumpy, pandas, polarsで計算します。
$(10^n, 2)$の行列をnpyとparquet形式で保存した時の容量と、ロード時間、計算時間をそれぞれ測定しました。
1. データ容量
データ容量 | $10^6$ | $10^7$ | $10^8$ | $10^9$ |
---|---|---|---|---|
.npy | 16 MB | 160 MB | 1.6 GB | 16 GB |
.parquet | 5.3 MB | 52.9 MB | 524.7 MB | 5.24 GB |
データ容量はparquet形式の方がnpy形式に比べて約$1/2$倍に削減されています。
ただparquetは基本的に2次元データでしか保存できないので、テーブルデータ以外ではnpyに比べて活用できる機会は少ないでしょう。
2. ロード時間[s]
ロード時間[s] | $10^6$ | $10^7$ | $10^8$ | $10^9$ |
---|---|---|---|---|
numpy | 0.0093 | 0.1276 | 1.0480 | 18.2100 |
pandas | 0.1072 | 0.2078 | 5.4981 | 78.1901 |
polars | 0.0406 | 0.1535 | 0.1535 | 19.5526 |
ロード時間はnumpyとpolarsが同じくらいで、pandasが一番遅い結果となりました。
同じparquetファイルをロードするだけでも、pandasに比べてpolarsの方が圧倒的に速いことがわかります。
ロードする回数があまり多くない状況では、numpyとpolarsの時間差は気にするほどではないと感じます。
3. 計算時間(和)[s]
計算時間(和)[s] | $10^6$ | $10^7$ | $10^8$ | $10^9$ |
---|---|---|---|---|
numpy | 0.0014 | 0.0842 | 4.5350 | 68.5682 |
pandas | 0.0054 | 0.0779 | 9.3288 | - |
polars | 0.0104 | 0.0473 | 0.9323 | 35.1551 |
最後にメインの計算時間です。
予想通りnumpyよりもpolarsの方が約2倍高速であることが確かめられました!
しかし$10^6$データではnumpyの方が速いので、小中規模データではnumpyの方が良さそうです。
*pandasでは$10^9$データを計算することはできませんでした。
結論
予想通り、大規模データではnumpyよりもpolarsの方が計算速度が速いという結果になりました。
ただ、今回計算したのは単なる列同士の和であり、行列の数値計算のメインである逆行列などでは普通にnumpyの方が速いと思います。なので今回の結果が役に立つような場面は限られていますが、可能性というタイトルなので大目に見ていただければと思います。
二次元データなら使えそうな気がするので、画像処理や時系列データなどに活用できないか色々調べてみたいと思います。ここまで読んでいただきありがとうございました。