2013-06-17 8 views
6

インタラクティブブローカーからのデータをSierra Chart経由で5秒間のOHLCVTバーから受け取るファイルからデータを取得しています。パンダ:floatとintのデータフレームへの追加が、NaNがいっぱいである場合よりも遅い

データフレームに新しい行を追加するのではなく、履歴ファイルを使用してデータフレームを作成し、正しいタイムスタンプで5000個の「空白」レコードを追加します。空白の行に新しい行を書き出し、タイムスタンプがない場合はすべての行を埋め、ポインタを更新します。

これはうまくいきます。現在はclasses and functionsです。私の初期のバージョンでは、5000行のNaN(OHLCVxyz)が作成されました。私はそうOHLCが浮いているとVxyzを使用してint型であることをゼロに「空白」レコードを変換し、エンド・データ・タイプで開始する整然とだろうと思った:

dg.iloc[0:5000] = 0.0 
dg[[v, x, y, z]] = dg[[v, x, y, z]].astype('int') 

これが唯一の追加5000行ごとに1回発生(一度HSIの場合は1日)。私が驚いたのは、読み書きループへの影響でした。それらは1行あたり0.8msから3.4msになりました。唯一の変更はNaNからゼロまででした。

This pictureはゼロ埋め込みフレーム(timestats 0.0038参照)、次にNaN塗りフレーム(timestats 0.0008)での実行を示します。

[NaN、NaN、NaN、NaN、NaN、NaN]の代わりに[0.0、0.0、0.0、0.0、0、0、0、0]のフィールドに書き込むのに時間がかかる理由について、 、NaN、NaN、NaN]

コードの改善についてのご意見もあります。 :)

おかげ

EDIT私はデータなしで誰でも実行することができ単純なモデルを構築し@BrenBarnからの質問に続いて 17時間

。そうすることで、NaNがそれに影響を与えるかどうかという疑問が解消されました。このバージョンでは、私は両方のバージョンに0.0sを書き込むことができたとの差は同じであった。

    フロートの8列を有するアレイは、4つのフロートの列とを有するアレイよりも速く10倍に追加さ
  • int64のうち4つ。
  • 追加される行は[1.0,2.0,3.0,4.0,5,6,7,8]
  • であり、追加は10000回self.df.iloc [self.end] = datarowで行われます。増分が終了します。

私は誤っていない限り(常に可能です)、4列の浮動小数点数と4つの整数を持つデータフレームに追加すると、10倍の時間がかかるようです。これはパンダの問題なのでしょうか?

here is the output picture

私はあなたがそれに追加する前に8列35万行の配列を持つことが大きな違いだと思います。最初のテストでは10行追加しても影響はありませんでした。私は戻って再テストする必要があります。

EDIT 10分

私は戻って、わずか10行のintialアレイと追加のループへの影響を作成しませんが、そうではない、その変化はなかったです元の配列/データフレームのサイズ私の以前のテストでは、カラムをintに変換したと思っていたが、私はそうしていなかっただろう - これをチェックすると、これを行うと思ったコマンドはそうではなかった。 35分

da = SierraFrame(range(10), np.zeros((10,8))) 
da.extend_frame1() 

EDITと可能性のある回答この質問は、より詳細に回答してはいけません。

ここで、私の仮説は、dfがすべてを含むならば、データフレームの[1.0,2.0,3.0,4.0,5,6,7,8]をスペアラインに追加する基本的な機能が異なるということです浮動小数点数と整数の列を含む場合よりも1つの型です。私はちょうどすべてのint64sでそれをテストしました、そして、平均加算は0.41ms対すべてのフロートの0.37msと混合データフレームのための2.8msでした。 Int8sは0.39msを要した。私は、その組み合わせがパンダのアクションを最適化する能力に影響を及ぼすと思います。効率が非常に重要な場合、すべての列が同じタイプ(おそらくfloat64)のデータフレームが最良の賭けです。

のPython 3.3.1を使用するLinux x64の上で実施した試験

+0

これらのセルに書き込むデータの種類は何ですか?また、あなたは正確に何をタイミングしていますか?零点の設定自体は時間のかかるものの一部である可能性はありますか? – BrenBarn

+0

ゼロ/タイプキャストの設定は、既存のファイルが読み込まれ、フレームが作成されたときに行われます。その後、ループがタイマーを開始し(各繰り返し)、新しいデータがあるかどうかテストされ、データがある場合は、4つの浮動小数点数と4つの整数を持つdatarowというリストにデータが変換され、self.df.iloc [ self.end] = datarow。データフレームへの変更もファイルに書き出されます。データがある場合のみ、現在の時間差がtime_listに追加され、統計が作成されます。 –

+0

読み取りと変換後のファイル書き込みが影響を与えている可能性を排除するために、私はそれをコメントアウトしました。これにより、両方の結果が〜0.4ミリ秒短縮されます。 –

答えて

5

this blog post by the main author of pandasで説明したように、パンダのデータフレームは、内部の "ブロック" で構成されています。ブロックは、すべて同じデータ型を持つ列のグループです。各ブロックは、ブロックタイプのnumpy配列として格納されます。したがって、5つのint列と5つのfloat列がある場合は、intブロックとfloatブロックがあります。

マルチタイプ配列に追加するには、基になるnumpy配列のそれぞれに追加する必要があります。 numpy配列への追加は、新しいnumpy配列全体を作成する必要があるため、遅いです。したがって、マルチタイプのDataFrameへの追加が遅いということは意味があります。すべての列が1つの型であれば、新しいnumpy配列を作成するだけですが、型が異なる場合は複数の新しいnumpy配列を作成する必要があります。

データをすべて同じタイプにすると、これが高速になることは事実です。しかし、主な結論は、「効率が重要な場合は、すべての列を同じタイプに保つ」ことではないと私は思います。効率が重要な場合は結論はです。配列/ DataFramesに追加しようとしないでください。

これはnumpyの動作方法です。 numpy配列で作業するのが最も遅い部分は、最初にそれらを作成することです。彼らは固定されたサイズを持っています。あなたが1つに「追加」すると、新しいサイズの全く新しいものを作成しているだけです。遅いです。あなたが絶対にそれらに追加する必要がある場合、あなたは多少の痛みを和らげるためにタイプを混乱させるようなものを試すことができます。しかし、究極的には、DataFrame(または一般的にnumpyの配列)に追加しようとするたびに、パフォーマンスが大幅に低下する可能性があります。

+0

そのBrenBarnに感謝します。私は@ジェフが正しいと私の元の質問は長すぎるとなっていることがわかります。実際、私は5000行ごとにしか追加していません。そして、ループされるタイミングは、データファイルを作成するためにメインファイルが読み込まれたときに実際に追加される行にデータを書き込むことです。 –

+0

addはself.df.iloc [self.end] = datarowで実行されます。ここで、datarowは常に4つの浮動小数点数と4つの整数のリストです。しかし、あなたの答えは、既存の行を上書きするのがなぜそれ以上の長さになるのか説明しています - パンダは、リストを2つの異なる配列(すべての浮動小数点数)で書くのに適したコードを使用しなければならないようです最適化されていません。もう1つ試してみよう:最初の半分に4つの浮動小数点を追加し、後半には4つの整数を追加して、タイミングがどうなるかを確認する。 –

+0

@ John9631:同じロジックが適用されます。複数のタイプのDataFrameにデータを書き込む場合、実際には2つの別々のnumpy配列への2回の書き込みが必要です。私は、この減速が追加のようになるとは思っていませんが、1つではなく2つの別々のnumpy操作が含まれています。 – BrenBarn

関連する問題