複数のスレッドを使用して、pandas データフレーム内のデータにアクセスして削除しています。このため、パンダのデータフレームはスレッドセーフなのだろうか?
2 に答える
いいえ、パンダはスレッドセーフではありません。そして、驚くべき方法でスレッドセーフではありません。
- 別のスレッドが使用している間に pandas データフレームから削除できますか?
それについてふざけた!いいえ。そして、一般的にいいえ。GIL ロックされた python データ構造でさえありません。
- 他の誰かが pandas オブジェクトに書き込んでいるときに、そのオブジェクトから読み取ることはできますか?
- スレッドで pandas データフレームをコピーして、そのコピーで作業できますか?
絶対にありません。長年の未解決の問題があります: https://github.com/pandas-dev/pandas/issues/2728
実際、これはかなり合理的な (つまり、予想される) 動作だと思います。次のいずれかでない限り、データ構造の書き込みと読み取り、またはコピーを同時に実行できるとは思いません。i) 並行性のために設計されているか、ii) そのオブジェクトとそこから派生したすべてのビュー オブジェクトを排他的にロックしています。それ(.loc
、.iloc
ビューであり、パンダには他のものがあります)。
- 他の誰も書き込みを行っていない pandas オブジェクトから読み取ることはできますか?
Python のほとんどすべてのデータ構造について、答えはイエスです。パンダの場合、いいえ。そして、現在のところ、それは設計目標ではないようです。
通常、誰も変更操作を実行していない場合は、オブジェクトに対して「読み取り」操作を実行できます。ただし、少し注意する必要があります。pandas を含む一部のデータ構造は、メモ化を実行して、それ以外の場合は機能的に純粋な高価な操作をキャッシュします。一般に、Python でロックレスメモ化を実装するのは簡単です。
@property
def thing(self):
if _thing is MISSING:
self._thing = self._calc_thing()
return self._thing
...シンプルで安全です(割り当てが安全にアトミックであると仮定します-すべての言語で常にそうであるとは限りませんが、オーバーライドしない限り、CPythonではそうです__setattribute__
)。
パンダ、シリーズ、およびデータフレームのインデックスは、最初の使用時に遅延計算されます。私は、それらが同様の安全な方法で行われることを願っています (ただし、ドキュメントには保証がありません)。
すべてのライブラリ (パンダを含む) について、誰も変更操作を実行していない場合、すべての種類の読み取り専用操作 (より具体的には、「機能的に純粋な」操作) がスレッドセーフであることを願っています。これは、スレッドセーフのための「妥当な」簡単に達成できる、一般的な、より低いバーだと思います。
ただし、パンダの場合、これを想定することはできません。オブジェクトに対して「機能的に不純な」操作 (セルへの書き込み、列の追加/削除など) を誰も実行していないことを保証できたとしても、pandas はスレッドセーフではありません。
最近の例を次に示します: https://github.com/pandas-dev/pandas/issues/25870 (これは .copy-not-threadsafe 問題の重複としてマークされていますが、別の問題である可能性があります)。
s = pd.Series(...)
f(s) # Success!
# Thread 1:
while True: f(s)
# Thread 2:
while True: f(s) # Exception !
... は失敗しf(s): s.reindex(..., copy=True)
、新しいオブジェクトとして結果を返します。これは機能的に純粋でスレッド セーフであると考えられます。残念ながら、そうではありません。
この結果、ヘルスケア分析システムの本番環境で pandas を使用できなくなりました。読み取り専用操作のメモリ内並列化が安全でなくなるため、内部開発には使用しないことをお勧めします。(!!)
そのreindex
行動は奇妙で驚くべきものです。失敗する理由について誰かが考えている場合は、ここで答えてください 。
メンテナーはこれをhttps://github.com/pandas-dev/pandas/issues/2728の複製としてマークしました 。私は疑わしいです.copy
が、ソースがあれば、ほとんどすべてのパンダはどのような状況でもスレッドセーフではありません(これは彼らのアドバイスです)。
!
基になる ndarrays のデータは、スレッドセーフな方法でアクセスでき、自己責任で変更できます。通常、DataFrame のサイズを変更するには新しいオブジェクトを作成する必要があるため、データの削除は困難です。将来的にはこれを変更したいと思います。