python - 使用线程同时写入多个 CSV 文件

标签 python pandas multithreading dataframe

我有一个包含多个数据帧的列表。这些数据帧可能非常大,需要一些时间才能写入 csv 文件。我正在尝试使用 pandas 将它们同时写入 csv 文件,并尝试使用多线程来减少时间。为什么多线程版本比顺序版本花费更多时间?使用 pandas 将文件写入 csv 不是 IO 绑定(bind)进程还是我没有正确实现它?

多线程:

list_of_dfs = [df_a, df_b, df_c]

start = time.time()

with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
    results = executor.map(lambda x: list_of_dfs[x].to_csv('Rough/'+str(x)+'.csv', index=False), range(0,3))
        
print(time.time()-start)
>>> 18.202364921569824

顺序:

start = time.time()

for i in range(0,3):
    list_of_dfs[i].to_csv('Rough/'+str(i)+'.csv', index=False)
    
print(time.time() - start)
>>> 13.783314228057861

最佳答案

我假设您使用常用的 CPython 解释器。

Why is the multithreading version taking more time than the sequential version?

答案可能就在于 CPython 全局解释器锁 (GIL)。

事实上,Pandas 使用 CPython 的内部 csv 库来编写 CSV 文件。然而,据我所知,csv 库(用 C 编写)从内存中读取基本的 Python 类型(因此它不知道 Numpy)并将它们格式化为字符串,以便可以将它们写入您的存储设备上。对 CPython 对象的访问受到 GIL 的保护,这会阻止任何加速(假设大部分时间都花在访问 CPython 对象上)。

Is writing a file to csv with pandas not an IO Bound Process or am I not implementing it correctly?

在现代机器(使用任何像样的 SSD)上,使用 Pandas 写入 CSV 文件显然不受 IO 限制。格式化过程非常慢(整数和浮点转换以及字符串处理)并且应该花费大部分时间。此外,它与缓慢的 CPython 对象访问交织在一起。这解释了为什么您不应该获得任何加速。

两个线程之间的

上下文切换通常会导致性能降低。您可以在 CPython documentation 中找到更多相关信息。本身:

The GIL can degrade performance even when it is not a bottleneck. Summarizing the linked slides: The system call overhead is significant, especially on multicore hardware. Two threads calling a function may take twice as much time as a single thread calling the function twice. The GIL can cause I/O-bound threads to be scheduled ahead of CPU-bound threads, and it prevents signals from being delivered.

关于python - 使用线程同时写入多个 CSV 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66805376/

相关文章:

python - 带字符串的几层 If 语句

c++ - c++ 11中的线程安全对象状态操作

c++ - 用 C++ 实现的可移植线程类

python - 为什么 python 的 timeit 使用 'best of 3' 来测量耗时?

python - 在 PyQt5 中显示和隐藏多个窗口

python - 从 Pygame 中的组中获取特定 Sprite

python - 如何用新名称替换特定标点符号?

python - numpy 基于 Mx1 矩阵创建 Mx2 矩阵

python - 在 matplotlib 中使用数据框日期列

objective-c - 使用异步 NSURLConnection 获取本地文件是否过度?