2012年にPandasがRのdata.tableマージよりもPythonでマージされたのはなぜですか?


160

私は最近、Python のパンダライブラリに出会いました。このベンチマークによると非常に高速なメモリ内マージを実行します。R(分析用に選択した私の言語)のdata.tableパッケージよりもさらに高速です。

なぜpandasこれよりずっと速いのですdata.tableか?PythonがRより優れているという固有の速度の利点が原因ですか、それとも私が気付いていないトレードオフがありますか?andにdata.table頼らずに内部結合と外部結合を実行する方法はありますか?merge(X, Y, all=FALSE)merge(X, Y, all=TRUE)

比較

以下は、さまざまなパッケージのベンチマークに使用されるRコードPythonコードです。


10
@JoshuaUlrich:IIRCはdata.tableから継承するだけですが、内部data.frameではCコードに依存しています。
digEmAll 2012年

4
@Joshua「data.framesをCで操作しても遅い」とはどういう意味ですか?それは他のものに関連していますか?そして、何が遅いのですか?
Matt Dowle、2012年

12
@JoshuaUlrich私はこのコメントの記録が決してベッドに置かれなかったことに気づきました。だからそれを明確にするために:この議論の直後set()に追加されましたdata.table。と非常によく似て:=いますが[.data.table、ループ時のオーバーヘッドが小さいため、と同じくらい高速matrixです。したがって、行列と同じくらい高速に操作data.frame できます。ベンチマークはこちらです。
Matt Dowle 2013年

5
このベンチマークの更新バージョンを入手できますか?このベンチが実際にはエッジケースであり、これは現在までに修正されていることは明らかです。私が見たすべてのベンチマークがdata.tableの方が速いことを示していることを考えると、マージ番号が何であるかを知りたいですか?
statquant

3
@statquant私は元のベンチマークを実行しませんでしたが、Wesがベンチマークを更新するのを見てみたいです。
ザック

回答:


120

data.table一意の文字列(レベル)の数が多い場合、ウェスが既知の問題を発見した可能性があります:10,000。

Rprof()通話に費やした時間のほとんどはわかりますsortedmatch(levels(i[[lc]]), levels(x[[rc]])か?これは実際には結合自体(アルゴリズム)ではなく、準備段階です。

最近の取り組みでは、キーに文字列を使用できるようになりました。これにより、R独自のグローバル文字列ハッシュテーブルとより密接に統合することで、この問題を解決できるはずです。いくつかのベンチマーク結果はすでに報告されtest.data.table()ていますが、そのコードは、レベルを一致するレベルに置き換えるためにまだ接続されていません。

パンダdata.tableは通常の整数列よりも速くマージされますか?これは、アルゴリズム自体と要因の問題を分離する方法になるはずです。

また、data.table持っている時系列マージ念頭に置いています。その2つの側面:i)(id、datetime)などの複数列の順序付けされたキーii)優勢な高速結合(roll=TRUE)別名持ち越された最後の観測。

これはdata.table、提示された比較との最初の比較であるため、確認にはしばらく時間がかかります。


2012年7月にリリースされたdata.table v1.8.0からの更新

  • タイプ 'factor'の列のiレベルをxレベルに一致させるときに、内部関数のsortmatch()が削除され、chmatch()に置き換えられました。この予備ステップは、ファクターカラムのレベル数が大きい場合(たとえば、> 10,000)、(既知の)大幅な速度低下を引き起こしていました。Wes McKinney(PythonパッケージPandasの作者)が実証したように、4つの列を結合するテストで悪化しました。たとえば、600,000個が一意である100万個の文字列の一致は、たとえば16秒から0.5秒に削減されました。

また、そのリリースでは:

  • 文字列がキーで許可され、因数分解よりも優先されます。data.table()とsetkey()は因数分解する文字を強制しなくなりました。ファクターは引き続きサポートされています。FR#1493、FR#1224、および(部分的に)FR#951を実装します。

  • 新しい関数chmatch()および%chin%、より高速なバージョンのmatch()および文字ベクトル用の%in%。Rの内部文字列キャッシュが利用されます(ハッシュテーブルは作成されません)。これらは、?chmatchの例のmatch()よりも約4倍高速です。

2013年9月現在、CRANのdata.tableはv1.8.10であり、v1.9.0に取り組んでいます。ニュースはライブで更新されます。


しかし、私が最初に書いたように、上記:

data.table時系列は、合併を念頭に。その2つの側面:i)(id、datetime)などの複数列の順序付けされたキーii)優勢な高速結合(roll=TRUE)別名持ち越された最後の観測。

したがって、Pandasの2つの文字列の等価結合は、おそらくdata.tableよりも高速です。結合された2つの列をハッシュするように聞こえるので。data.tableは、一般的な順序結合を考慮しているため、キーをハッシュしません。data.tableの「キー」は、文字通り単にソート順です(SQLのクラスター化インデックスに似ています。つまり、RAMでのデータの順序付けです)。リストには、たとえば、セカンダリキーを追加します。

要約すると、既知の問題が修正されているため、10,000を超える一意の文字列を使用したこの特定の2文字の列のテストで強調された明白な速度の違いは、それほど悪くないはずです。


6
かなり大規模で現実的なデータセットのテストケースを提供していただければ、ベンチマークを実行させていただきます。あなたも大歓迎です。私は実際にはまだ整数結合キーの場合のコードを最適化していません(それを私のtodoリストに入れてください!)が、リンクされたプレゼンテーションのハッシュテーブルの研究を考えると、文字列の場合よりもはるかに優れたパフォーマンスを期待できます。
ウェスマッキニー

22
私はこれらのライブラリのどちらも使用していませんが、R側からの建設的な応答をMatthew Dowleの形で見ることができてうれしいです。
SlowLearner 2012年

3
これがRprofの結果pastie.org/3258362です。結合タイプによっては、ソートされたマッチに費やされる時間の20〜40%のようです。整数列に調べる必要があります別のtime--私はそのような場合(最適化するために、私を思い出させるためにGitHubの問題パンダを作っgithub.com/wesm/pandas/issues/682
ウェス・マッキニー

14
@AndyHayden改善は少し前に行われました。NEWSアイテムで編集します。Wesは、その既知の問題を解決する1つの特定のテスト(2つの文字列を結合するのと同じ)を選びました。もし彼が整数列を選んだなら、それは違っていただろう。そして、彼が会議でベンチマークを発表する前に私に注意を向けていたなら、私は彼に既知の問題についてもっと話すことができただろう。
Matt Dowle 2013

191

パンダが速い理由は、高速ハッシュテーブルの実装-klibとC / Cythonを使用し非常に慎重に実装された、より良いアルゴリズムを考え出したためです。ベクトル化できない部分のPythonインタープリターオーバーヘッドを回避するためです。このアルゴリズムについては、私のプレゼンテーションで詳しく説明しています。パンダの設計と開発の内部の様子

比較は、data.tableRさんの全体のポイントがあるため、実際にビット面白いですdata.table、それが含まれていることである事前計算されたインデックスをさまざまな列は、データの選択やマージなどの作業を加速するため。この場合(データベース結合)、pandasのDataFrameには、マージに使用されている事前計算された情報が含まれていないため、いわば「コールド」マージです。因数分解がこのアルゴリズムの最大のボトルネックであるため、結合キーの因数分解バージョンを保存していた場合、結合は大幅に速くなります。

また、パンダのDataFrameの内部デザインは、Rのdata.frame(内部の配列のリストにすぎません)よりも、この種の操作にはるかに対応しやすいことも付け加えておきます。


76
もちろん、すべてをpythonで理解したので、Rに変換するのは簡単です;)
ハドリー

37
しかし、なぜ誰もがそうしたいのでしょうか?:)
12

9
うーん...多分彼らはRでデータ操作をより速くしたいのでしょうか?ただ推測します:))
lebatsnok

28
こんにちはウェス-の結果data.tableは主にバグが修正されたために発生したものと思われます。ベンチマークを再実行して、更新されたブログ投稿を作成できる可能性はありますか?
ザック14

6
:ザックのことを確認してくださいあなたは、このチェックアウトgithub.com/Rdatatable/data.table/wiki/Benchmarks-:-Grouping
Merik

37

このトピックは2歳ですが、パンダとデータの比較を検索するときに着陸する可能性が高い場所のようです。

これらは両方とも時間とともに進化してきたので、興味のあるユーザーのためにここに比較的新しい比較(2014年から)を投稿したいと思います。https//github.com/Rdatatable/data.table/wiki/Benchmarks--Grouping

Wesおよび/またはMatt(ちなみに、それぞれPandasとdata.tableの作成者であり、上記の両方にコメントしている)がここに追加するニュースがあるかどうかを知ることは興味深いでしょう。

-更新-

jangoreckiが以下に投稿したコメントには、私が非常に役立つと思うリンクが含まれています。https//github.com/szilard/benchm-databases

https://github.com/szilard/benchm-databases/blob/master/plot.png

このグラフは、さまざまなテクノロジーの集約および結合操作の平均時間を示しています(低い=速い ;比較は2016年9月に最終更新)。本当に勉強になりました。

質問への背中を行く、R DT keyそしてR DTRのdata.tableのキー/キーなしのフレーバーを参照し、Pythonのパンダよりも、このベンチマークで速くすることが起こります(Py pandas)。


1
これを投稿しようとしていました!追加していただきありがとうございます。
Zach

7
:@Zachこの参照github.com/szilard/benchm-databases:それはあまりにもいいですspeakerdeck.com/szilard/...
jangorecki

1
@Zachの4年後、新しいベンチマーク結果がついに登場しました。以下の私の回答を参照してください。
jangorecki

7

特に、質問の対象となる両方のツールの作成者によるすばらしい回答があります。Mattの回答は、質問で報告されたケースを説明しています。これは、マージアルゴリズムではなく、バグによって引き起こされたものです。バグは翌日、7年以上前に修正されました。

私の答えでは、data.tableとpandasのマージ操作のいくつかの最新のタイミングを提供します。plyrとbase Rマージは含まれていないことに注意してください。

私が提示しているタイミングは、継続的に実行される再現可能なベンチマークであるdb-benchmarkプロジェクトからのものです。ツールを最新バージョンにアップグレードし、ベンチマークスクリプトを再実行します。他の多くのソフトウェアソリューションを実行します。Sparkに興味がある場合は、Daskや他のいくつかのリンクを確認してください。


現在のところ...(まだ実装されていません:データサイズが1つ増え、質問が5つ増えます)

LHSテーブルの2つの異なるデータサイズをテストします。
これらのデータサイズごとに、5つの異なるマージ質問を実行します。

Q1:LHS内側はRHS-参加 整数に
Q2:LHS内側整数でRHS媒体に参加
Q3:LHS 外側は整数でRHS媒体に参加
Q4:LHS内側が上RHS媒体を結合因子(カテゴリ)
Q5:LHSインナーRHS-に参加します 整数に 大きな

RHSテーブルには3つのサイズがあります

  • smallはLHS / 1e6のサイズに変換されます
  • 媒体はLHS / 1e3のサイズに変換されます
  • bigはLHSのサイズに変換されます

すべてのケースで、LHSとRHSの間で一致する行の約90%があり、RHS結合列に重複はありません(デカルト積はありません)。


現在(2019年11月2日に実行)

2019年11月1日にリリースされたパンダ0.25.3
data.table 0.12.7(92abb70)が2019年11月2日にリリースされました

LHSの2つの異なるデータサイズについて、以下のタイミングは秒単位です。列にpd2dtは、パンダがdata.tableよりも遅い回数の比率を格納するフィールドが追加されています。

  • 0.5 GB LHSデータ
+-----------+--------------+----------+--------+
| question  |  data.table  |  pandas  |  pd2dt |
+-----------+--------------+----------+--------+
| q1        |        0.51  |    3.60  |      7 |
| q2        |        0.50  |    7.37  |     14 |
| q3        |        0.90  |    4.82  |      5 |
| q4        |        0.47  |    5.86  |     12 |
| q5        |        2.55  |   54.10  |     21 |
+-----------+--------------+----------+--------+
  • 5 GB LHSデータ
+-----------+--------------+----------+--------+
| question  |  data.table  |  pandas  |  pd2dt |
+-----------+--------------+----------+--------+
| q1        |        6.32  |    89.0  |     14 |
| q2        |        5.72  |   108.0  |     18 |
| q3        |       11.00  |    56.9  |      5 |
| q4        |        5.57  |    90.1  |     16 |
| q5        |       30.70  |   731.0  |     23 |
+-----------+--------------+----------+--------+

今後ともよろしくお願いします!data.tableのR vs python実装の列を追加できますか?
ザック

1
R dtとパンダを比較する場合でも、ウェブサイトにアクセスして確認するだけでよいと思います。そして、pyDTは元の質問の一部ではありませんでした。
jangorecki
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.