python pandas dataframe线程安全吗?

标签 python thread-safety pandas

我正在使用多个线程来访问和删除我的 pandas 数据框中的数据。因此,我想知道 pandas dataframe 线程安全吗?

最佳答案

不,pandas 不是线程安全的。而且它以令人惊讶的方式不是线程安全的。

  • 我可以在另一个线程正在使用时从 pandas dataframe 中删除吗?

搞砸了!没有。通常没有。甚至对于 GIL 锁定的 Python 数据结构也不行。

  • 我可以在其他人正在写入 pandas 对象时读取它吗?
  • 我可以在我的线程中复制一个 pandas 数据框,然后处理副本吗?

绝对不是。有一个长期悬而未决的问题:https://github.com/pandas-dev/pandas/issues/2728

实际上我认为这是非常合理的(即预期的)行为。我不希望能够同时写入、读取或复制任何数据结构,除非:i) 它是为并发而设计的,或者 ii) 我对该对象和所有 View 都有独占锁从它派生的对象(.loc.iloc 是 View ,pandas 可能还有其他 View )。

  • 我可以在没有其他人写入的情况下从 pandas 对象读取数据吗?

对于Python中几乎所有的数据结构,答案都是肯定的。对于 Pandas ,不。而且目前看来,这不是设计目标。

通常,如果没有人执行变异操作,您可以对对象执行“读取”操作。不过,您必须谨慎一点。一些数据结构,包括 pandas,执行记忆化,以缓存昂贵的操作,而这些操作在其他方面是纯功能的。在 Python 中实现无锁内存通常很容易:

@property
def thing(self):
    if _thing is MISSING:
        self._thing = self._calc_thing()
    return self._thing

...它简单且安全(假设赋值是安全的原子性——并非所有语言都如此,但在 CPython 中是这样,除非您覆盖 __setattribute__)。

Pandas、series 和 dataframe 索引在首次使用时会延迟计算。我希望(但我没有在文档中看到保证)它们以类似的安全方式完成。

对于所有库(包括 pandas),我希望如果没有人执行变异,所有类型的只读操作(或更具体地说,“功能纯”操作)都是线程安全的操作。我认为这是一个“合理的”、易于实现的、常见的、较低的线程安全标准。

但是,对于 Pandas ,您不能假设这一点。 即使您可以保证没有人在您的对象上执行“功能上不纯”的操作(例如写入单元格、添加/删除列),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 !

... fails for f(s): s.reindex(..., copy=True),它返回它的结果作为新对象——你会认为它在功能上是纯净且线程安全。不幸的是,事实并非如此。

这样做的结果是我们无法在生产中为我们的医疗保健分析系统使用 pandas - 我现在不鼓励将它用于内部开发,因为它会使只读操作的内存并行化变得不安全。 (!!)

reindex 行为很奇怪而且令人惊讶。如果有人知道失败原因,请在此处回答:What's the source of thread-unsafety in this usage of pandas.Series.reindex(, copy=True)?

维护人员将此标记为 https://github.com/pandas-dev/pandas/issues/2728 的副本.我很怀疑,但如果 .copy 是来源,那么几乎所有的 pandas 在任何情况下都不是线程安全的(这是他们的建议)。

!

关于python pandas dataframe线程安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13592618/

相关文章:

c++ - 将线程安全添加到简单的日志记录功能?

python - 过滤具有连续数字的行

Python Selenium - 在文本框中输入值

Python 猴子补丁私有(private)函数

python - 在 Python 中的同一点快速评估多个函数

python - Pandas:将开始/结束事件分组为间隔

python - 使用条件更改列值或附加新行的数据框更新 SQLite DB

python - 使用 python 绘制曲线而不是条形图

Java同步-不正确的发布

c++ - 为什么 boost::shared_ptr 使用 gcc 内联汇编来增加 use_count 而不是使用 operator++?