python pandas dataframe thread safe?

jgovgodb  于 2023-06-20  发布在  Python
关注(0)|答案(2)|浏览(180)

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

uttx8gqw

uttx8gqw1#

不,pandas不是线程安全的。而且它的线程安全性并不令人惊讶。

  • 当另一个线程正在使用时,我可以从pandas数据框中删除吗?

该死的!没有。一般来说也没有。即使是GIL锁定的Python数据结构也不行。

  • 当别人正在向pandas对象写入时,我可以读取它吗?
  • 我可以在我的线程中复制一个pandas数据框架,并进行复制吗?

绝对不是有一个长期悬而未决的问题https://github.com/pandas-dev/pandas/issues/2728
我认为这是相当合理的(即。预期)行为。我不希望能够同时读写任何数据结构,除非:i)它是为并发而设计的,或者ii)我对该对象 * 和从它派生的所有视图对象 * 有一个排他锁(.loc.iloc是视图,pandas有其他视图)。

  • 我可以在没有其他人向pandas对象写入时读取它吗?

对于Python中几乎所有的数据结构,答案都是肯定的。对于Pandas来说,不是。这似乎不是目前的设计目标。
通常,如果没有人在执行变异操作,则可以对对象执行“读取”操作。不过,你得谨慎一点。一些数据结构,包括pandas,执行memoization,以缓存昂贵的操作,否则功能纯。在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 !

...对于f(s): s.reindex(..., copy=True)失败,它返回的结果a作为新对象--你会认为它在功能上是纯的,线程安全的。不幸的是,事实并非如此。
这样做的结果是,我们无法在生产环境中为我们的医疗分析系统使用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 * 在任何情况下都不是线程安全的(这是他们的建议)。
!

pbgvytdp

pbgvytdp2#

底层ndarray中的数据可以以线程安全的方式访问,并由您自行承担修改风险。删除数据会很困难,因为更改DataFrame的大小通常需要创建一个新对象。我想在未来的某个时候改变这个。

相关问题