さまざまなPythonプロセスでDataFrameをリアルタイムで更新する


8

たとえば、キュ​​ーイングシステムから毎秒約500行(これをさらに並列化して約50 psに減らすことができます)でリアルタイムにデータを収集し、それを DataFrame

rq = MyRedisQueue(..)
df = pd.DataFrame()
while 1:
    recv = rq.get(block=True)
    # some converting
    df.append(recv, ignore_index = True)

ここで問題は、このデータに基づいてCPUをどのように利用するかです。したがって、私はGILの制限を完全に認識しており、ここでもマルチプロセッシングマネージャーの 名前空間を調べましたが、中央に保持されるデータフレームのレイテンシに関していくつかの欠点あるようです。それを掘り下げる前に、プロセス間に適用するために私が認識したものを試してみました、これは遅くなり、オーバーヘッドが多すぎます。pool.mappickle

したがって、これが最後に疑問に思いました。1秒あたり500行(または1秒あたり50行)の挿入を別のプロセスに転送して、子のデータに統計とヒューリスティックを適用するためのCPU時間を残すにはどうすればよいでしょうか。プロセス?

多分それは2つのプロセスの間にカスタムTCPソケットまたはキューシステムを実装する方が良いでしょうか?または、親プロセス内の1つの大きなデータフレームへの高速アクセスを実際に許可するための実装pandasまたは他のライブラリーはありますか?パンダ大好き!


毎秒新しい50から500行のチャンクについてのみ統計を実行し、それを1つの大きなDFに継続的に追加しますか?大きなDFを保存する必要がありますか、それとも実行するためにより多くのリアルタイム処理が必要ですか?
ロナルドリュック

@RonaldLuc必要な場合は、新しく50〜500行の統計に制限します。大きなDataFrameの既存のデータを追跡するために、追加の変数に平均値と高値/安値を保持できます。
gies0r

回答:


4

始める前に、あなたはコードについてはあまり話さなかったが、50/500の新しい行を1秒ごとに子プロセスに転送し、その大きな子プロセスを作成しようとすることを念頭に置いておく必要がありDataFrameます。

私はあなたとまったく同じプロジェクトに取り組んでいます。Pythonには、ご存じのように、多くのIPC実装がPipeありQueueます。Shared Memory解決策は多くの場合問題があるかもしれません、AFAIK python公式ドキュメント共有メモリの使用について警告しました。

私の経験では、2つのプロセス間でのみデータを変換する最良の方法はなので、DataFrameをピクルして、他の接続エンドポイントに送信できます。ソケット()を使用しないことを強くお勧めします。PipeTCPAF_INET

パンダDataFrameは、漬けたり漬けたりしないと別のプロセスに変換できません。したがって、生データdictをDataFrameではなく組み込み型として転送することもお勧めします。これにより、ピクルとピッキング解除が速くなり、メモリフットプリントも少なくなります。


回答@AmirHmZに感謝します!特にベンチマークへのリンクは素晴らしいです(そして私がまだ知らなかったその周りのツール)。Shared Memory親プロセスへの書き込みアクセスをほとんど制限しなければ、この領域のソリューション-メインプロセスが追加している間に子プロセスからの多くの読み取りプロセスを処理できると期待できます-は私が見ているものからそれを行うことができます。
gies0r

..しかし、それが何かに書いてあるのかどうかshared memoryはわかりませんblock state。つまり、子プロセスはDataFrameを読み取ることができませんが、親プロセスはDataFrameに追加します(ほとんどの場合)。
gies0r

@ gies0r非アクティブで申し訳ありません。Shared Memoryソリューションを使用する場合は、子プロセスをサプライヤープロセスと同期させる必要があります。それはによって行うことができるmultiprocessing.Lockdocs.python.org/3/library/...
AmirHmZ

0

の並列化 pandasは、おそらく別のエンジンで完全に処理するほうが適切です。

見ていDatabricksによってコアラプロジェクトまたはDASKのデータフレームを


ええと、それは非常に膨大な量のコードをレビューして修正する必要があります... Dasksは順応性が高いように見えますが、それでも大量の作業です。質問で述べたようなデータのロード/更新間隔が実装/文書化されている例を知っていますか?
gies0r

Daskを使用して200 GB以上のデータセットを並列処理し、メモリフットプリントを小さくしましたが、オンラインではありませんでした。Dask は基本的に、多くのパンダデータフレームが互いに積み重ねられたものです。
ロナルドリュック

@RonaldLucローカルマシンでどのような操作をしましたか?
Datanovice

寄木細工、行ごとの数値演算、位置情報の計算、「ローカルパンダDataFrame」(df.map_partitions)のいくつかの演算から読み込み、次にgroupbyインデックス(Dask でのパフォーマンスにとって重要)をCSVとして保存します。
ロナルドリュック

0

簡単な解決策は、プロセスを2つの異なる段階に分けることです。Asyncioを使用して、ブロックしない方法でデータを受信し、その中で変換を実行します。第2段階では、Asyncioキューを使用してDataFrameを構築します。これは、Redisキューからデータを受信して​​いる間、別のプロセスでDataFrameを使用する必要がないことを前提としています。

これは、Asyncioを使用してプロデューサー/コンシューマーモデルを構築する例です

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.