将多处理和并行性应用于 numpy 函数

Applying multi processing and parallelism to numpy functions

我正在尝试并行化我的 numpy 代码以使其更快。原始的 numpy 数组 list_ 有超过 200 万个变量,因此很难计算这就是为什么我试图用 numpy 和多处理函数来计算我的计算。我如何利用下面的代码来处理多处理单元。我在下面有一个代码,我已经尝试过多处理,但我认为它不是很有效。函数 ym, xym ,std 是独立的,因此可以对这些函数进行多重处理,但是 mk,bk 依赖于 ym, xym ,std 函数。

原版 Python 版本

import numpy as np
number = 5
list_= np.array([457.334015,424.440002,394.795990,408.903992,398.821014,402.152008,435.790985,423.204987,411.574005,
404.424988,399.519989,377.181000,375.467010,386.944000,383.614990,375.071991,359.511993,328.865997,
320.510010,330.079010,336.187012,352.940002,365.026001,361.562012,362.299011,378.549011,390.414001,
400.869995,394.773010,382.556000])
ym = (np.convolve(list_, np.ones(shape=(number)), mode='valid')/number)[:-1]
xym = (np.convolve(list_, np.arange(number, 0, -1), mode='valid'))[:-1]
mk = (x_mean* ym- xym)/(np.power(x_mean,2)- x_squared_mean)
bk = ym - mk*x_mean
std = np.array([list_[i:i+number].std() for i in range(0, len(list_)-number)])

多处理版本

#x_mean and x_squared is used for the lin regressions and stand dev
x_mean = number/2*(1 + number)
x_squared_mean = number*(number+1)*(2*number+1)/6

def ym():   
    ym = (np.convolve(PC_list, np.ones(shape=(number)), mode='valid')/number)[:-1]
    print(ym)
def xym():
    xym = (np.convolve(PC_list, np.arange(number, 0, -1), mode='valid'))[:-1]
    print(xym)
def std():
    std = np.array([PC_list[i:i+number].std() for i in range(0, len(PC_list)-number)])
    print(std)
    
#setting up the multi processing vars     
p1 = multiprocessing.Process(target=ym)
p2 = multiprocessing.Process(target=xym)
p3 = multiprocessing.Process(target=std)

#running the multi processes 
p1.start()
p2.start()
p3.start()

p1.join()
p2.join()
p3.join()

xym()
ym()
std()

因为 mkbk 确实依赖于 ymxym,所以你无能为力,你必须先计算它们然后你可以在接下来的计算中使用。

我做了一个快速基准测试,看起来即使我有一个 2000 万的数组,卷积、mkbk 都在 0.3 秒以下 运行。代码中真正的瓶颈是 std 函数。那是因为您使用的 python for 循环很慢。

Numba 助你一臂之力

我建议调查 numba。它可以将您的常规 python 函数编译成优化的机器代码,并使它们 运行 非常快!它有一些限制,但对于您的情况,它会完美地工作。尝试将 std 函数更改为:

from numba import njit

@njit 
def std_numba(x, n):
    std = np.array([x[i:i+n].std() for i in range(0, len(x)-n)])
    return std

即使没有任何类型的多处理,所有计算 运行 在一个 运行dom 数组上 运行 200 万个浮点数。