7

シエラ チャート経由で Interactive Brokers の 5 秒 OHLCVT バーからデータを受け取るファイルからデータを取得しています。

以前の投稿のアドバイスに従って、データフレームに新しい行を追加するのではなく、履歴ファイルを使用してデータフレームを作成し、正しいタイムスタンプで 5000 個の「空白」レコードを追加します。次に、空白行の上に新しい行をそれぞれ書き込み、タイムスタンプが欠落している場合はすべての行を埋め、ポインターを更新します。

これはうまくいきます。現在のクラスと関数は次のとおりです。私の最初のバージョンでは、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.8 ミリ秒から 3.4 ミリ秒になりました。唯一の変更は、NaN からゼロへの変更でした。

この図は、ゼロで満たされたフレーム (timestats 0.0038 を参照) での最初の実行と、NaN で満たされたフレーム (timestats 0.0008) での実行を示しています。

[NaN、NaN、NaN、NaN、NaN、NaN、NaNの代わりに[0.0、0.0、0.0、0.0、0、0、0、0]のフィールドに書き込むのに時間がかかる理由について、誰でも洞察を提供できますか? 、NaN] ?

コードの改善に関するご意見も大歓迎です。:)

ありがとう

編集+17 時間

@BrenBarn からの質問に従って、データがなくても誰でも実行できる、より単純なモデルを構築しました。そうすることで、NaN が影響を与えるかどうかという問題を排除しました。このバージョンでは、両方のバージョンに 0.0 を書き込むことができ、違いは同じでした:

  • 8 列の float を持つ配列は、4 列の float と 4 つの int64 を持つ配列よりも 10 倍速く追加されます。
  • いずれの場合も、追加される行は [1.0, 2.0, 3.0, 4.0, 5, 6, 7, 8] でした
  • 追加は、self.df.iloc[self.end] = datarow とインクリメント end で 10000 回行われます。

したがって、私が間違っていない限り (常に可能です)、float の 4 列と int の 4 列を持つデータフレームに追加すると、10 倍の時間がかかるようです。これはパンダの問題ですか、それとも期待すべきことですか?

ここにテストコードが あり、ここに出力画像があります

追加する前に 8 列の 350,000 行の配列を持っていると、大きな違いが生じると思います。10 行に追加する最初のテストでは影響は見られませんでした。戻って再テストする必要があります。

編集+10 分

いいえ、戻って 10 行のみの初期配列を作成しましたが、追加ループへの影響は変わらなかったため、元の配列/データフレームのサイズではありません。おそらく、以前のテストで、列を int に変換したと思っていたのですが、変換していなかったのです。

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

編集と可能な回答+35 分

この質問にもっと詳しく答えないでください。

この時点で、私の仮説は、[1.0、2.0、3.0、4.0、5、6、7、8] をデータフレームの予備の行に追加する基本的な機能は、df が 1 つのタイプすべてを含む場合と、それが含む場合とでは異なるというものです。 float と int の列。すべてのint64でテストしたところ、平均追加は0.41msでしたが、すべてのフロートでは0.37ms、混合データフレームでは2.8msでした。Int8s は 0.39ms かかりました。ミックスはパンダのアクションを最適化する能力に影響を与えると思うので、効率が非常に重要な場合は、すべての列が同じタイプ(おそらくfloat64)のデータフレームが最善の策です。

Linux x64 で Python 3.3.1 を使用して実施されたテスト

4

1 に答える 1