我有一个字典(在内存中)data
,它有大约 10,000 个键,每个键代表一个股票行情,值存储每日股票价格时间序列数据的 pandas 数据帧表示。我正在尝试计算成对 Pearson correlation 。
该代码需要花费约 3 小时的较长时间来完全迭代所有组合 O(n^2) ~ C(2, 10000)
。我尝试使用 multiprocessing虚拟包,但根本没有看到任何性能提升(实际上随着工作线程数量的增加而变慢)。
from multiprocessing.dummy import Pool
def calculate_correlation((t1, t2)):
# pseudo code here
return pearsonr(data[t1]['Close'], data[t2]['Close'])
todos = []
for idx, t1 in enumerate(list(data.keys())):
for t2 in list(data.keys())[idx:]: # only the matrix top triangle
todos.append((t1, t2))
pool = Pool(4)
results = pool.map(calculate_correlation, todos)
pool.close()
pool.join()
所有数据都已加载到内存中,因此不应该是 IO 密集型的。有什么原因导致性能根本没有提升吗?
最佳答案
当您使用 multiprocessing.dummy 时,您使用的是线程,而不是进程。对于 Python 中受 CPU 限制的应用程序,使用多线程时通常不会获得性能提升。您应该使用多处理来并行化 Python 中的代码。因此,如果您将代码更改为
from multiprocessing.dummy import Pool
至
from multiprocessing import Pool
这应该会大大提高您的表现。
以上内容可以解决您的问题,但如果您想知道为什么会发生这种情况。请继续阅读:
Python 中的多线程具有全局解释器锁 (GIL),可防止同一进程中的两个线程同时运行。如果发生大量磁盘 IO,多线程会有所帮助,因为磁盘 IO 是可以处理锁的单独进程。或者,如果您的 Python 代码使用一个单独的应用程序来处理锁,那么多线程将会有所帮助。另一方面,与多线程相反,多处理将使用 CPU 的所有核心作为单独的进程。在像您这样的 CPU 密集型 Python 应用程序中,如果您使用多处理而不是多线程,您的应用程序将在多个内核上的多个进程上并行运行,这将提高应用程序的性能。
关于python - Pandas DataFrame 多线程没有性能提升,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51809619/